using std::set;
using std::string;
-list<string> TarSegmentStore::norefs;
-
Tarfile::Tarfile(const string &path, const string &segment)
: size(0),
segment_name(segment)
Tarfile::~Tarfile()
{
- string checksum_list = checksums.str();
- internal_write_object(segment_name + "/checksums",
- checksum_list.data(), checksum_list.size());
tar_append_eof(t);
if (tar_close(t) != 0)
string path = segment_name + "/" + buf;
internal_write_object(path, data, len);
-
- // Compute a checksum for the data block, which will be stored at the end
- // of the TAR file.
- SHA1Checksum hash;
- hash.process(data, len);
- sprintf(buf, "%08x", id);
- checksums << buf << " " << hash.checksum_str() << "\n";
}
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,
- const std::list<std::string> &refs)
+ std::string &group)
{
struct segment_info *segment;
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<string>::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)
fprintf(stderr, "Closing segment group %s (%s)\n",
group.c_str(), segment->name.c_str());
- string reflist;
- for (set<string>::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;
{
}
-void LbsObject::add_reference(const LbsObject *o)
-{
- refs.insert(o->get_name());
-}
-
void LbsObject::write(TarSegmentStore *store)
{
assert(data != NULL);
assert(!written);
- list<string> reflist;
- for (set<string>::iterator i = refs.begin(); i != refs.end(); ++i) {
- reflist.push_back(*i);
- }
-
- name = store->write_object(data, data_len, group, reflist);
+ name = store->write_object(data, data_len, group);
written = true;
data = NULL;
private:
size_t size;
std::string segment_name;
- std::ostringstream checksums;
TAR *t;
};
// 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::list<std::string> &refs = norefs);
+ const std::string &group = "");
// Ensure all segments have been fully written.
void sync();
std::string path;
std::map<std::string, struct segment_info *> 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<std::string> norefs;
-
// Ensure that all segments in the given group have been fully written.
void close_segment(const std::string &group);
// segment. Until that time, its name cannot be determined.
std::string get_name() const { return name; }
- // Logically, one object may reference other objects (such as a metadata
- // listing referncing actual file data blocks). Such references should be
- // noted explicitly. It may eventually be used to build up a tree of
- // checksums for later verifying integrity.
- void add_reference(const LbsObject *o);
-
private:
std::string group;
const char *data;