Track which objects are used in which snapshots in the local database.
[cumulus.git] / scandir.cc
index a227bb3..f8f6127 100644 (file)
@@ -22,6 +22,7 @@
 #include <set>
 
 #include "format.h"
+#include "localdb.h"
 #include "store.h"
 #include "sha1.h"
 
@@ -38,6 +39,10 @@ static char *block_buf;
 
 static const size_t LBS_METADATA_BLOCK_SIZE = 65536;
 
+/* Local database, which tracks objects written in this and previous
+ * invocations to help in creating incremental snapshots. */
+LocalDb *db;
+
 /* Contents of the root object.  This will contain a set of indirect links to
  * the metadata objects. */
 std::ostringstream metadata_root;
@@ -126,15 +131,27 @@ int64_t dumpfile(int fd, dictionary &file_info)
 
         hash.process(block_buf, bytes);
 
-        // tarstore processing
-        LbsObject *o = new LbsObject;
-        o->set_group("data");
-        o->set_data(block_buf, bytes);
-        o->write(tss);
-        object_list.push_back(o->get_name());
-        segment_list.insert(o->get_ref().get_segment());
-        delete o;
+        // Either find a copy of this block in an already-existing segment, or
+        // index it so it can be re-used in the future
+        SHA1Checksum block_hash;
+        block_hash.process(block_buf, bytes);
+        string block_csum = block_hash.checksum_str();
+        ObjectReference ref = db->FindObject(block_csum, bytes);
+
+        // Store a copy of the object if one does not yet exist
+        if (ref.get_segment().size() == 0) {
+            LbsObject *o = new LbsObject;
+            o->set_group("data");
+            o->set_data(block_buf, bytes);
+            o->write(tss);
+            ref = o->get_ref();
+            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;
     }
 
@@ -352,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) {
@@ -380,6 +404,8 @@ int main(int argc, char *argv[])
         descriptor << "    " << *i << "\n";
     }
 
+    db->Close();
+
     tss->sync();
     delete tss;