summaryrefslogtreecommitdiff
path: root/src/storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/storage.cpp')
-rw-r--r--src/storage.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/storage.cpp b/src/storage.cpp
index 366fe71..19f35a9 100644
--- a/src/storage.cpp
+++ b/src/storage.cpp
@@ -746,7 +746,11 @@ optional<PartialObject> PartialStorage::loadObject(const Digest & digest) const
}
PartialRef PartialStorage::storeObject(const PartialObject & obj) const
-{ return ref(p->storeBytes(obj.encode())); }
+{
+ if (not obj)
+ return PartialRef::zcreate(*this);
+ return ref(p->storeBytes(obj.encode()));
+}
PartialRef PartialStorage::storeObject(const PartialRecord & val) const
{ return storeObject(PartialObject(val)); }
@@ -775,6 +779,8 @@ Ref Storage::storeObject(const Blob & val) const
template<class S>
optional<Digest> Storage::Priv::copy(const typename S::Ref & pref, vector<Digest> * missing) const
{
+ if (pref.digest().isZero())
+ return pref.digest();
if (backend->contains(pref.digest()))
return pref.digest();
if (pref)
@@ -787,6 +793,9 @@ optional<Digest> Storage::Priv::copy(const typename S::Ref & pref, vector<Digest
template<class S>
optional<Digest> Storage::Priv::copy(const ObjectT<S> & pobj, vector<Digest> * missing) const
{
+ if (not pobj)
+ return Digest(array<uint8_t, Digest::size> {});
+
bool fail = false;
if (auto rec = pobj.asRecord())
for (const auto & r : rec->items().asRef())
@@ -948,6 +957,11 @@ PartialRef PartialRef::create(const PartialStorage & st, const Digest & digest)
return PartialRef(shared_ptr<Priv>(p));
}
+PartialRef PartialRef::zcreate(const PartialStorage & st)
+{
+ return create(st, Digest(array<uint8_t, Digest::size> {}));
+}
+
const Digest & PartialRef::digest() const
{
return p->digest;
@@ -1421,9 +1435,6 @@ vector<uint8_t> RecordT<S>::encodeInner() const
vector<uint8_t> res;
auto inserter = std::back_inserter(res);
for (const auto & item : *ptr) {
- copy(item.name.begin(), item.name.end(), inserter);
- inserter = ':';
-
string type;
string value;
@@ -1451,6 +1462,8 @@ vector<uint8_t> RecordT<S>::encodeInner() const
value = string(*x);
} else if (auto x = item.asRef()) {
type = "r";
+ if (x->digest().isZero())
+ continue;
value = string(x->digest());
} else if (auto x = item.asUnknown()) {
type = x->type;
@@ -1459,6 +1472,8 @@ vector<uint8_t> RecordT<S>::encodeInner() const
throw runtime_error("unhandeled record item type");
}
+ copy(item.name.begin(), item.name.end(), inserter);
+ inserter = ':';
copy(type.begin(), type.end(), inserter);
inserter = ' ';
@@ -1599,6 +1614,12 @@ ObjectT<S> ObjectT<S>::load(const typename S::Ref & ref)
}
template<class S>
+ObjectT<S>::operator bool() const
+{
+ return not holds_alternative<monostate>(content);
+}
+
+template<class S>
optional<RecordT<S>> ObjectT<S>::asRecord() const
{
if (holds_alternative<RecordT<S>>(content))