Miscellaneous changes.
[cumulus.git] / scandir.cc
index c6879d2..c11c561 100644 (file)
 
 #include <algorithm>
 #include <string>
+#include <list>
 #include <vector>
 #include <iostream>
 #include <sstream>
 
 #include "format.h"
 #include "store.h"
-#include "tarstore.h"
 #include "sha1.h"
 
+using std::list;
 using std::string;
 using std::vector;
 using std::ostream;
@@ -71,7 +72,7 @@ void dumpfile(int fd, dictionary &file_info, ostream &metadata)
     struct stat stat_buf;
     fstat(fd, &stat_buf);
     int64_t size = 0;
-    string segment_list = "";
+    list<string> segment_list;
 
     if ((stat_buf.st_mode & S_IFMT) != S_IFREG) {
         printf("file is no longer a regular file!\n");
@@ -91,16 +92,44 @@ void dumpfile(int fd, dictionary &file_info, ostream &metadata)
         hash.process(block_buf, bytes);
 
         // tarstore processing
-        string blockid = tss->write_object(block_buf, bytes, "data");
-        if (segment_list.size() > 0)
-            segment_list += " ";
-        segment_list += blockid;
+        LbsObject *o = new LbsObject;
+        o->set_group("data");
+        o->set_data(block_buf, bytes);
+        o->write(tss);
+        segment_list.push_back(o->get_name());
+        delete o;
 
         size += bytes;
     }
 
     file_info["checksum"] = hash.checksum_str();
-    file_info["data"] = segment_list;
+
+    /* For files that only need to be broken apart into a few objects, store
+     * the list of objects directly.  For larger files, store the data
+     * out-of-line and provide a pointer to the indrect object. */
+    if (segment_list.size() < 8) {
+        string blocklist = "";
+        for (list<string>::iterator i = segment_list.begin();
+             i != segment_list.end(); ++i) {
+            if (i != segment_list.begin())
+                blocklist += " ";
+            blocklist += *i;
+        }
+        file_info["data"] = blocklist;
+    } else {
+        string blocklist = "";
+        for (list<string>::iterator i = segment_list.begin();
+             i != segment_list.end(); ++i) {
+            blocklist += *i + "\n";
+        }
+
+        LbsObject *i = new LbsObject;
+        i->set_group("indirect");
+        i->set_data(blocklist.data(), blocklist.size());
+        i->write(tss);
+        file_info["data"] = "@" + i->get_name();
+        delete i;
+    }
 }
 
 void scanfile(const string& path, ostream &metadata)
@@ -110,6 +139,7 @@ void scanfile(const string& path, ostream &metadata)
     struct stat stat_buf;
     char *buf;
     ssize_t len;
+    list<string> refs;
 
     // Set to true if the item is a directory and we should recursively scan
     bool recurse = false;
@@ -246,7 +276,11 @@ int main(int argc, char *argv[])
 {
     block_buf = new char[LBS_BLOCK_SIZE];
 
-    tss = new TarSegmentStore(".");
+    if (argc > 1) {
+        tss = new TarSegmentStore(argv[1]);
+    } else {
+        tss = new TarSegmentStore(".");
+    }
 
     std::ostringstream metadata;
 
@@ -257,7 +291,12 @@ int main(int argc, char *argv[])
     }
 
     const string md = metadata.str();
-    string root = tss->write_object(md.data(), md.size(), "root");
+
+    LbsObject *r = new LbsObject;
+    r->set_group("root");
+    r->set_data(md.data(), md.size());
+    r->write(tss);
+    delete r;
 
     tss->sync();
     delete tss;