From d60ac6ffaac11851042a5978ac10f52293a50b50 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Thu, 3 May 2007 14:23:21 -0700 Subject: [PATCH] Partial support for tracker inter-object references. --- scandir.cc | 1 + tarstore.cc | 28 +++++++++++++++++++++++++++- tarstore.h | 20 ++++++++++++++++---- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/scandir.cc b/scandir.cc index 20f8351..1616187 100644 --- a/scandir.cc +++ b/scandir.cc @@ -132,6 +132,7 @@ void scanfile(const string& path, ostream &metadata) struct stat stat_buf; char *buf; ssize_t len; + list refs; // Set to true if the item is a directory and we should recursively scan bool recurse = false; diff --git a/tarstore.cc b/tarstore.cc index b90426b..5133c66 100644 --- a/tarstore.cc +++ b/tarstore.cc @@ -14,13 +14,19 @@ #include #include +#include +#include #include #include #include "tarstore.h" +using std::list; +using std::set; using std::string; +list TarSegmentStore::norefs; + Tarfile::Tarfile(const string &path, const string &segment) : size(0), segment_name(segment) @@ -99,7 +105,8 @@ void Tarfile::internal_write_object(const string &path, static const size_t SEGMENT_SIZE = 4 * 1024 * 1024; string TarSegmentStore::write_object(const char *data, size_t len, const - std::string &group) + std::string &group, + const std::list &refs) { struct segment_info *segment; @@ -133,6 +140,12 @@ string TarSegmentStore::write_object(const char *data, size_t len, const string full_name = segment->name + "/" + id_buf; + // Store any dependencies this object has on other segments, so they can be + // written when the segment is closed. + for (list::const_iterator i = refs.begin(); i != refs.end(); ++i) { + segment->refs.insert(*i); + } + // If this segment meets or exceeds the size target, close it so that // future objects will go into a new segment. if (segment->file->size_estimate() >= SEGMENT_SIZE) @@ -153,7 +166,20 @@ void TarSegmentStore::close_segment(const string &group) fprintf(stderr, "Closing segment group %s (%s)\n", group.c_str(), segment->name.c_str()); + string reflist; + for (set::iterator i = segment->refs.begin(); + i != segment->refs.end(); ++i) { + reflist += *i + "\n"; + } + segment->file->internal_write_object(segment->name + "/references", + reflist.data(), reflist.size()); + delete segment->file; segments.erase(segments.find(group)); delete segment; } + +string TarSegmentStore::object_reference_to_segment(const string &object) +{ + return object; +} diff --git a/tarstore.h b/tarstore.h index ebf4061..a657ec9 100644 --- a/tarstore.h +++ b/tarstore.h @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -31,10 +33,10 @@ public: // Return an estimate of the size of the file. size_t size_estimate() { return size; } -private: void internal_write_object(const std::string &path, const char *data, size_t len); +private: size_t size; std::string segment_name; std::ostringstream checksums; @@ -52,7 +54,8 @@ public: // used to control object placement; objects with different group // parameters are kept in separate segments. std::string write_object(const char *data, size_t len, - const std::string &group = ""); + const std::string &group = "", + const std::list &refs = norefs); // Ensure all segments have been fully written. void sync(); @@ -60,15 +63,24 @@ public: private: struct segment_info { Tarfile *file; - std::string name; // UUID - int count; // Objects written to this segment + std::string name; // UUID + std::set refs; // Other segments this one refers to + int count; // Objects written to this segment }; std::string path; std::map segments; + // An empty list which can be used as an argument to write_object to + // indicate that this object depends on no others. + static std::list norefs; + // Ensure that all segments in the given group have been fully written. void close_segment(const std::string &group); + + // Parse an object reference string and return just the segment name + // portion. + std::string object_reference_to_segment(const std::string &object); }; #endif // _LBS_TARSTORE_H -- 2.20.1