summaryrefslogtreecommitdiff
path: root/src/storage.cpp
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-04-16 21:42:45 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2020-04-16 21:42:45 +0200
commit6cf5244bc514042fe419fffe1cd26a7f5e3c778f (patch)
tree4a72abf80980c3d10656bd82606a69329867d057 /src/storage.cpp
parenta76a9ad65fa549d2c1650bb5a7d9a657186edc43 (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.cpp34
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;