diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2020-04-16 21:42:45 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2020-04-16 21:42:45 +0200 |
commit | 6cf5244bc514042fe419fffe1cd26a7f5e3c778f (patch) | |
tree | 4a72abf80980c3d10656bd82606a69329867d057 /src/storage.cpp | |
parent | a76a9ad65fa549d2c1650bb5a7d9a657186edc43 (diff) |
Remove optional from load result
Makes loading of data well-defined for arbitrary object contents.
Introduce zero reference and object to represent missing or mismatched
parts.
Diffstat (limited to 'src/storage.cpp')
-rw-r--r-- | src/storage.cpp | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/src/storage.cpp b/src/storage.cpp index 81a70e1..6a0669c 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -315,6 +315,11 @@ optional<Ref> Storage::ref(const Digest & digest) const return Ref::create(*this, digest); } +Ref Storage::zref() const +{ + return Ref::zcreate(*this); +} + Digest PartialStorage::Priv::storeBytes(const vector<uint8_t> & content) const { array<uint8_t, Digest::size> arr; @@ -346,6 +351,8 @@ optional<vector<uint8_t>> PartialStorage::Priv::loadBytes(const Digest & digest) optional<PartialObject> PartialStorage::loadObject(const Digest & digest) const { + if (digest.isZero()) + return PartialObject(monostate()); if (auto content = p->loadBytes(digest)) return PartialObject::decode(*this, *content); return nullopt; @@ -362,6 +369,8 @@ PartialRef PartialStorage::storeObject(const Blob & val) const optional<Object> Storage::loadObject(const Digest & digest) const { + if (digest.isZero()) + return Object(monostate()); if (auto content = p->loadBytes(digest)) return Object::decode(*this, *content); return nullopt; @@ -466,6 +475,13 @@ Digest::operator string() const return res; } +bool Digest::isZero() const +{ + for (uint8_t x : value) + if (x) return false; + return true; +} + PartialRef PartialRef::create(PartialStorage st, const Digest & digest) { @@ -517,6 +533,16 @@ optional<Ref> Ref::create(Storage st, const Digest & digest) return Ref(shared_ptr<Priv>(p)); } +Ref Ref::zcreate(Storage st) +{ + auto p = new Priv { + .storage = make_unique<PartialStorage>(st), + .digest = Digest(array<uint8_t, Digest::size> {}), + }; + + return Ref(shared_ptr<Priv>(p)); +} + const Object Ref::operator*() const { if (auto res = static_cast<Storage*>(p->storage.get())->loadObject(p->digest)) @@ -854,11 +880,9 @@ vector<uint8_t> ObjectT<S>::encode() const } template<class S> -optional<ObjectT<S>> ObjectT<S>::load(const typename S::Ref & ref) +ObjectT<S> ObjectT<S>::load(const typename S::Ref & ref) { - if (ref) - return *ref; - return nullopt; + return *ref; } template<class S> @@ -899,7 +923,7 @@ vector<Stored<Object>> erebos::collectStoredObjects(const Stored<Object> & from) if (auto rec = cur->asRecord()) for (const auto & item : rec->items()) if (auto ref = item.asRef()) - queue.push_back(*Stored<Object>::load(*ref)); + queue.push_back(Stored<Object>::load(*ref)); } return res; |