diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2020-01-04 21:07:33 +0100 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2020-01-04 21:29:00 +0100 | 
| commit | 2059c09154870d704d26d10f0462db1e9b4ea676 (patch) | |
| tree | c256c807500c498452de3c82b695a59f990b606f /include | |
| parent | b97b503408911130d24d7f07f9247dca8314a316 (diff) | |
Partial and memory-backed storage
Diffstat (limited to 'include')
| -rw-r--r-- | include/erebos/storage.h | 163 | 
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()); |