From 6cf5244bc514042fe419fffe1cd26a7f5e3c778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Thu, 16 Apr 2020 21:42:45 +0200 Subject: 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. --- src/storage.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/storage.cpp') 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 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 & content) const { array arr; @@ -346,6 +351,8 @@ optional> PartialStorage::Priv::loadBytes(const Digest & digest) optional 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 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::create(Storage st, const Digest & digest) return Ref(shared_ptr(p)); } +Ref Ref::zcreate(Storage st) +{ + auto p = new Priv { + .storage = make_unique(st), + .digest = Digest(array {}), + }; + + return Ref(shared_ptr(p)); +} + const Object Ref::operator*() const { if (auto res = static_cast(p->storage.get())->loadObject(p->digest)) @@ -854,11 +880,9 @@ vector ObjectT::encode() const } template -optional> ObjectT::load(const typename S::Ref & ref) +ObjectT ObjectT::load(const typename S::Ref & ref) { - if (ref) - return *ref; - return nullopt; + return *ref; } template @@ -899,7 +923,7 @@ vector> erebos::collectStoredObjects(const Stored & from) if (auto rec = cur->asRecord()) for (const auto & item : rec->items()) if (auto ref = item.asRef()) - queue.push_back(*Stored::load(*ref)); + queue.push_back(Stored::load(*ref)); } return res; -- cgit v1.2.3