Track which objects are used in which snapshots in the local database.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 15 May 2007 19:58:01 +0000 (12:58 -0700)
committerMichael Vrable <mvrable@turin.ucsd.edu>
Tue, 15 May 2007 19:58:01 +0000 (12:58 -0700)
localdb.cc
localdb.h
scandir.cc
schema.sql

index 733babd..27fec5a 100644 (file)
 
 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);
+}
index 6035e5d..3a88870 100644 (file)
--- a/localdb.h
+++ b/localdb.h
 
 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;
 };
 
index 0dfdbdb..f8f6127 100644 (file)
@@ -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) {
index 114670c..8518c4f 100644 (file)
@@ -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
+);