summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-01-04 21:07:33 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2020-01-04 21:29:00 +0100
commit2059c09154870d704d26d10f0462db1e9b4ea676 (patch)
treec256c807500c498452de3c82b695a59f990b606f /include
parentb97b503408911130d24d7f07f9247dca8314a316 (diff)
Partial and memory-backed storage
Diffstat (limited to 'include')
-rw-r--r--include/erebos/storage.h163
1 files changed, 115 insertions, 48 deletions
diff --git a/include/erebos/storage.h b/include/erebos/storage.h
index edb0aca..51fa3a4 100644
--- a/include/erebos/storage.h
+++ b/include/erebos/storage.h
@@ -12,39 +12,75 @@
namespace erebos {
class Storage;
+class PartialStorage;
class Digest;
class Ref;
-class Object;
+class PartialRef;
+
+template<class S> class RecordT;
+typedef RecordT<Storage> Record;
+typedef RecordT<PartialStorage> PartialRecord;
+template<class S> class ObjectT;
+typedef ObjectT<Storage> Object;
+typedef ObjectT<PartialStorage> PartialObject;
+class Blob;
+
template<typename T> class Stored;
-class Storage
+class PartialStorage
{
public:
- Storage(const Storage &) = default;
- Storage & operator=(const Storage &) = delete;
+ typedef erebos::PartialRef Ref;
+
+ PartialStorage(const PartialStorage &) = default;
+ PartialStorage & operator=(const PartialStorage &) = default;
+ virtual ~PartialStorage() = default;
+
+ bool operator==(const PartialStorage &) const;
+ bool operator!=(const PartialStorage &) const;
- static std::optional<Storage> open(std::filesystem::path path);
+ PartialRef ref(const Digest &) const;
- bool operator==(const Storage &) const;
- bool operator!=(const Storage &) const;
+ std::optional<PartialObject> loadObject(const Digest &) const;
+ PartialRef storeObject(const PartialObject &) const;
+ PartialRef storeObject(const PartialRecord &) const;
+ PartialRef storeObject(const Blob &) const;
+
+protected:
+ friend class Storage;
+ friend erebos::Ref;
+ friend erebos::PartialRef;
+ struct Priv;
+ const std::shared_ptr<const Priv> p;
+ PartialStorage(const std::shared_ptr<const Priv> p): p(p) {}
+};
+
+class Storage : public PartialStorage
+{
+public:
+ typedef erebos::Ref Ref;
+
+ Storage(const std::filesystem::path &);
+ Storage(const Storage &) = default;
+ Storage & operator=(const Storage &) = default;
+
+ Storage deriveEphemeralStorage() const;
+ PartialStorage derivePartialStorage() const;
std::optional<Ref> ref(const Digest &) const;
std::optional<Object> loadObject(const Digest &) const;
Ref storeObject(const Object &) const;
- Ref storeObject(const class Record &) const;
- Ref storeObject(const class Blob &) const;
+ Ref storeObject(const Record &) const;
+ Ref storeObject(const Blob &) const;
template<typename T> Stored<T> store(const T &) const;
void storeKey(Ref pubref, const std::vector<uint8_t> &) const;
std::optional<std::vector<uint8_t>> loadKey(Ref pubref) const;
-private:
- friend class Ref;
- struct Priv;
- const std::shared_ptr<const Priv> p;
- Storage(const std::shared_ptr<const Priv> p): p(p) {}
+protected:
+ Storage(const std::shared_ptr<const Priv> p): PartialStorage(p) {}
};
class Digest
@@ -72,28 +108,49 @@ private:
std::array<uint8_t, size> value;
};
-class Ref
+class PartialRef
{
public:
- Ref(const Ref &) = default;
- Ref & operator=(const Ref &) = delete;
+ PartialRef(const PartialRef &) = default;
+ PartialRef & operator=(const PartialRef &) = default;
- static std::optional<Ref> create(Storage, const Digest &);
+ static PartialRef create(PartialStorage, const Digest &);
const Digest & digest() const;
- const Object & operator*() const;
- const Object * operator->() const;
- const Storage & storage() const;
+ operator bool() const;
+ const PartialObject operator*() const;
+ std::unique_ptr<PartialObject> operator->() const;
-private:
+ const PartialStorage & storage() const;
+
+protected:
friend class Storage;
struct Priv;
const std::shared_ptr<const Priv> p;
- Ref(const std::shared_ptr<const Priv> p): p(p) {}
+ PartialRef(const std::shared_ptr<const Priv> p): p(p) {}
+};
+
+class Ref : public PartialRef
+{
+public:
+ Ref(const Ref &) = default;
+ Ref & operator=(const Ref &) = default;
+
+ static std::optional<Ref> create(Storage, const Digest &);
+
+ constexpr operator bool() const { return true; }
+ const Object operator*() const;
+ std::unique_ptr<Object> operator->() const;
+
+ const Storage & storage() const;
+
+protected:
+ Ref(const std::shared_ptr<const Priv> p): PartialRef(p) {}
};
-class Record
+template<class S>
+class RecordT
{
public:
class Item {
@@ -103,7 +160,7 @@ public:
int,
std::string,
std::vector<uint8_t>,
- Ref> Variant;
+ typename S::Ref> Variant;
Item(const std::string & name):
Item(name, std::monostate()) {}
@@ -121,7 +178,7 @@ public:
std::optional<int> asInteger() const;
std::optional<std::string> asText() const;
std::optional<std::vector<uint8_t>> asBinary() const;
- std::optional<Ref> asRef() const;
+ std::optional<typename S::Ref> asRef() const;
template<typename T> std::optional<Stored<T>> as() const;
@@ -130,12 +187,12 @@ public:
};
private:
- Record(const std::shared_ptr<std::vector<Item>> & ptr):
+ RecordT(const std::shared_ptr<std::vector<Item>> & ptr):
ptr(ptr) {}
public:
- Record(const std::vector<Item> &);
- Record(std::vector<Item> &&);
+ RecordT(const std::vector<Item> &);
+ RecordT(std::vector<Item> &&);
std::vector<uint8_t> encode() const;
const std::vector<Item> & items() const;
@@ -144,15 +201,18 @@ public:
std::vector<Item> items(const std::string & name) const;
private:
- friend class Object;
+ friend ObjectT<S>;
std::vector<uint8_t> encodeInner() const;
- static Record decode(Storage,
+ static std::optional<RecordT<S>> decode(const S &,
std::vector<uint8_t>::const_iterator,
std::vector<uint8_t>::const_iterator);
const std::shared_ptr<const std::vector<Item>> ptr;
};
+extern template class RecordT<Storage>;
+extern template class RecordT<PartialStorage>;
+
class Blob
{
public:
@@ -162,9 +222,10 @@ public:
std::vector<uint8_t> encode() const;
private:
- friend class Object;
+ friend Object;
+ friend PartialObject;
std::vector<uint8_t> encodeInner() const;
- static Blob decode(Storage,
+ static Blob decode(
std::vector<uint8_t>::const_iterator,
std::vector<uint8_t>::const_iterator);
@@ -173,41 +234,47 @@ private:
const std::shared_ptr<const std::vector<uint8_t>> ptr;
};
-class Object
+template<class S>
+class ObjectT
{
public:
typedef std::variant<
- Record,
+ RecordT<S>,
Blob> Variants;
- Object(const Object &) = default;
- Object(Variants content): content(content) {}
- Object & operator=(const Object &) = delete;
+ ObjectT(const ObjectT<S> &) = default;
+ ObjectT(Variants content): content(content) {}
+ ObjectT<S> & operator=(const ObjectT<S> &) = default;
- static std::optional<std::tuple<Object, std::vector<uint8_t>::const_iterator>>
- decodePrefix(Storage, std::vector<uint8_t>::const_iterator,
+ static std::optional<std::tuple<ObjectT<S>, std::vector<uint8_t>::const_iterator>>
+ decodePrefix(const S &,
+ std::vector<uint8_t>::const_iterator,
std::vector<uint8_t>::const_iterator);
- static std::optional<Object> decode(Storage, const std::vector<uint8_t> &);
- static std::optional<Object> decode(Storage,
+ static std::optional<ObjectT<S>> decode(const S &, const std::vector<uint8_t> &);
+ static std::optional<ObjectT<S>> decode(const S &,
std::vector<uint8_t>::const_iterator,
std::vector<uint8_t>::const_iterator);
- static std::vector<Object> decodeMany(Storage, const std::vector<uint8_t> &);
+ static std::vector<ObjectT<S>> decodeMany(const S &, const std::vector<uint8_t> &);
std::vector<uint8_t> encode() const;
- static std::optional<Object> load(const Ref &);
+ static std::optional<ObjectT<S>> load(const typename S::Ref &);
- std::optional<Record> asRecord() const;
+ std::optional<RecordT<S>> asRecord() const;
std::optional<Blob> asBlob() const;
private:
- friend class Record;
- friend class Blob;
+ friend RecordT<S>;
+ friend Blob;
Variants content;
};
+extern template class ObjectT<Storage>;
+extern template class ObjectT<PartialStorage>;
+
+template<class S>
template<typename T>
-std::optional<Stored<T>> Record::Item::as() const
+std::optional<Stored<T>> RecordT<S>::Item::as() const
{
if (auto ref = asRef())
return Stored<T>::load(ref.value());