X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=store.h;h=0bc21717dae7f9d63a2e5ba53beb6bf2415b80b6;hb=25b6639fb1783e0061affa177e6d6d2131c457f5;hp=3725a9f3cd99ff5018e7d234eb58f78660dd8ce5;hpb=a81fd6242d4a4076b7c79213de8cc7e13a311e56;p=cumulus.git diff --git a/store.h b/store.h index 3725a9f..0bc2171 100644 --- a/store.h +++ b/store.h @@ -14,6 +14,9 @@ #include #include #include +#include + +#include "sha1.h" /* In memory datatype to represent key/value pairs of information, such as file * metadata. Currently implemented as map. */ @@ -97,10 +100,97 @@ private: FILE *f; }; +/* An OutputStream which is simply sends writes to another OutputStream, but + * does provide separate tracking of bytes written. */ +class WrapperOutputStream : public OutputStream { +public: + explicit WrapperOutputStream(OutputStream &o); + virtual ~WrapperOutputStream() { } + +protected: + virtual void write_internal(const void *data, size_t len); + +private: + OutputStream ℜ +}; + +/* Like WrapperOutputStream, but additionally computes a checksum of data as it + * is written. */ +class ChecksumOutputStream : public OutputStream { +public: + explicit ChecksumOutputStream(OutputStream &o); + virtual ~ChecksumOutputStream() { } + + /* Once a checksum is computed, no further data should be written to the + * stream. */ + const uint8_t *finish_and_checksum(); + size_t checksum_size() const { return csum.checksum_size(); } + +protected: + virtual void write_internal(const void *data, size_t len); + +private: + OutputStream ℜ + SHA1Checksum csum; +}; + /* Simple wrappers that encode integers using a StringOutputStream and return * the encoded result. */ std::string encode_u16(uint16_t val); std::string encode_u32(uint32_t val); std::string encode_u64(uint64_t val); +struct uuid { + uint8_t bytes[16]; +}; + +/* A class which is used to pack multiple objects into a single segment, with a + * lookup table to quickly locate each object. Call new_object() to get an + * OutputStream to which a new object may be written, and optionally + * finish_object() when finished writing the current object. Only one object + * may be written to a segment at a time; if multiple objects must be written + * concurrently, they must be to different segments. */ +class SegmentWriter { +public: + SegmentWriter(OutputStream *output, struct uuid u); + ~SegmentWriter(); + + struct uuid get_uuid() const { return id; } + + // Start writing out a new object to this segment. + OutputStream *new_object(); + void finish_object(); + + // Utility functions for generating and formatting UUIDs for display. + static struct uuid generate_uuid(); + static std::string format_uuid(const struct uuid u); + +private: + typedef std::vector > object_table; + + ChecksumOutputStream *out; // Output stream with checksumming enabled + OutputStream *raw_out; // Raw output stream, without checksumming + struct uuid id; + + int64_t object_start_offset; + OutputStream *object_stream; + + object_table objects; +}; + +/* A SegmentStore, as the name suggests, is used to store the contents of many + * segments. The SegmentStore internally tracks where data should be placed + * (such as a local directory or remote storage), and allows new segments to be + * easily created as needed. */ +class SegmentStore { +public: + // New segments will be stored in the given directory. + SegmentStore(const std::string &path); + + SegmentWriter *new_segment(); + +private: + std::string directory; +}; + #endif // _LBS_STORE_H