From: Michael Vrable Date: Tue, 15 May 2007 19:58:01 +0000 (-0700) Subject: Track which objects are used in which snapshots in the local database. X-Git-Url: http://git.vrable.net/?p=cumulus.git;a=commitdiff_plain;h=da87780779a2f165503d019ee0b59d10e5d31ec8 Track which objects are used in which snapshots in the local database. --- diff --git a/localdb.cc b/localdb.cc index 733babd..27fec5a 100644 --- a/localdb.cc +++ b/localdb.cc @@ -22,10 +22,12 @@ using std::string; -void LocalDb::Open(const char *path) +void LocalDb::Open(const char *path, const char *snapshot_name) { int rc; + snapshot = snapshot_name; + rc = sqlite3_open(path, &db); if (rc) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); @@ -115,3 +117,33 @@ ObjectReference LocalDb::FindObject(const string &checksum, int64_t size) return ref; } + +void LocalDb::UseObject(const ObjectReference& ref) +{ + int rc; + sqlite3_stmt *stmt; + static const char s[] = + "insert into snapshot_contents " + "select blockid, ? as snapshot from block_index " + "where segment = ? and object = ?"; + const char *tail; + + rc = sqlite3_prepare_v2(db, s, strlen(s), &stmt, &tail); + if (rc != SQLITE_OK) { + return; + } + + sqlite3_bind_text(stmt, 1, snapshot.c_str(), snapshot.size(), + SQLITE_TRANSIENT); + string seg = ref.get_segment(); + sqlite3_bind_text(stmt, 2, seg.c_str(), seg.size(), SQLITE_TRANSIENT); + string obj = ref.get_sequence(); + sqlite3_bind_text(stmt, 3, obj.c_str(), obj.size(), SQLITE_TRANSIENT); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + fprintf(stderr, "Could not execute INSERT statement!\n"); + } + + sqlite3_finalize(stmt); +} diff --git a/localdb.h b/localdb.h index 6035e5d..3a88870 100644 --- a/localdb.h +++ b/localdb.h @@ -21,12 +21,14 @@ class LocalDb { public: - void Open(const char *path); + void Open(const char *path, const char *snapshot_name); void Close(); void StoreObject(const ObjectReference& ref, const std::string &checksum, int64_t size); ObjectReference FindObject(const std::string &checksum, int64_t size); + void UseObject(const ObjectReference& ref); private: + std::string snapshot; sqlite3 *db; }; diff --git a/scandir.cc b/scandir.cc index 0dfdbdb..f8f6127 100644 --- a/scandir.cc +++ b/scandir.cc @@ -148,8 +148,10 @@ int64_t dumpfile(int fd, dictionary &file_info) db->StoreObject(ref, block_csum, bytes); delete o; } + object_list.push_back(ref.to_string()); segment_list.insert(ref.get_segment()); + db->UseObject(ref); size += bytes; } @@ -355,10 +357,6 @@ int main(int argc, char *argv[]) tss = new TarSegmentStore(backup_dest); - string database_path = backup_dest + "/localdb.sqlite"; - db = new LocalDb; - db->Open(database_path.c_str()); - /* Write a backup descriptor file, which says which segments are needed and * where to start to restore this snapshot. The filename is based on the * current time. */ @@ -371,6 +369,13 @@ int main(int argc, char *argv[]) string desc_filename = backup_dest + "/" + desc_buf + ".lbs"; std::ofstream descriptor(desc_filename.c_str()); + /* Open the local database which tracks all objects that are stored + * remotely, for efficient incrementals. Provide it with the name of this + * snapshot. */ + string database_path = backup_dest + "/localdb.sqlite"; + db = new LocalDb; + db->Open(database_path.c_str(), desc_buf); + try { scanfile("."); } catch (IOException e) { diff --git a/schema.sql b/schema.sql index 114670c..8518c4f 100644 --- a/schema.sql +++ b/schema.sql @@ -3,7 +3,7 @@ -- -- The index is stored in an SQLite3 database. This is its schema. --- Index of all blocks which have been stored in one snapshot, by checksum. +-- Index of all blocks which have been stored in a snapshot, by checksum. create table block_index ( blockid integer primary key, segment text, @@ -12,3 +12,10 @@ create table block_index ( size integer ); create index block_content_index on block_index(checksum); +create index block_name_index on block_index(segment, object); + +-- Index tracking which blocks are used by which snapshots. +create table snapshot_contents ( + blockid integer, + snapshot text +);