summaryrefslogtreecommitdiff
path: root/src/storage.cpp
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2022-08-08 22:25:46 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2022-08-08 22:50:27 +0200
commit7aa7649e980ff4b335b41eaea34a9a11820c3e2d (patch)
tree0da4b7c4bf0e80e58d75dcac83b052a22a829985 /src/storage.cpp
parent5cfdbc49647b6be943d01e4ab141b705e9e5c86d (diff)
Generation number of stored objects with caching
Diffstat (limited to 'src/storage.cpp')
-rw-r--r--src/storage.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/storage.cpp b/src/storage.cpp
index 05b100a..5784309 100644
--- a/src/storage.cpp
+++ b/src/storage.cpp
@@ -979,6 +979,56 @@ const Storage & Ref::storage() const
return *static_cast<const Storage*>(p->storage.get());
}
+vector<Ref> Ref::previous() const
+{
+ auto rec = (**this).asRecord();
+ if (!rec)
+ return {};
+
+ vector<Ref> res;
+
+ auto sdata = rec->item("SDATA").asRef();
+ if (sdata) {
+ auto drec = sdata.value()->asRecord();
+ if (!drec)
+ return {};
+
+ for (const Record::Item & i : drec->items("SPREV"))
+ if (auto x = i.asRef())
+ res.push_back(*x);
+ return res;
+ }
+
+ for (const Record::Item & i : rec->items("PREV"))
+ if (auto x = i.asRef())
+ res.push_back(*x);
+ return res;
+}
+
+Generation Ref::generation() const
+{
+ scoped_lock lock(p->storage->p->generationCacheLock);
+ return generationLocked();
+}
+
+Generation Ref::generationLocked() const
+{
+ auto it = p->storage->p->generationCache.find(p->digest);
+ if (it != p->storage->p->generationCache.end())
+ return it->second;
+
+ auto prev = previous();
+ vector<Generation> pgen;
+ pgen.reserve(prev.size());
+ for (const auto & r : prev)
+ pgen.push_back(r.generationLocked());
+
+ auto gen = Generation::next(pgen);
+
+ p->storage->p->generationCache.emplace(p->digest, gen);
+ return gen;
+}
+
template<class S>
RecordT<S>::Item::operator bool() const
@@ -1366,6 +1416,25 @@ optional<Blob> ObjectT<S>::asBlob() const
template class erebos::ObjectT<Storage>;
template class erebos::ObjectT<PartialStorage>;
+
+Generation::Generation(): Generation(0) {}
+Generation::Generation(size_t g): gen(g) {}
+
+Generation Generation::next(const vector<Generation> & prev)
+{
+ Generation ret;
+ for (const auto g : prev)
+ if (ret.gen <= g.gen)
+ ret.gen = g.gen + 1;
+ return ret;
+}
+
+Generation::operator string() const
+{
+ return to_string(gen);
+}
+
+
vector<Stored<Object>> erebos::collectStoredObjects(const Stored<Object> & from)
{
unordered_set<Digest> seen;