summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2022-10-09 23:02:54 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2022-11-01 22:36:45 +0100
commit4d82c7e2704c035e33b9b606c409e5fac0f4f708 (patch)
treed03922bdf7f9cac0be99605244306bd7ef0f4803 /include
parentc6d01458b4545500a964491c2602da3c3079bfc2 (diff)
Stored set
Diffstat (limited to 'include')
-rw-r--r--include/erebos/merge.h20
-rw-r--r--include/erebos/set.h96
-rw-r--r--include/erebos/storage.h10
3 files changed, 126 insertions, 0 deletions
diff --git a/include/erebos/merge.h b/include/erebos/merge.h
new file mode 100644
index 0000000..bef8212
--- /dev/null
+++ b/include/erebos/merge.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <erebos/storage.h>
+
+namespace erebos
+{
+
+template<class T> struct Mergeable
+{
+};
+
+template<> struct Mergeable<vector<Stored<Object>>>
+{
+ using Component = Object;
+
+ static vector<Stored<Object>> components(const vector<Stored<Object>> & x) { return x; }
+ static vector<Stored<Object>> merge(const vector<Stored<Object>> & x) { return x; }
+};
+
+}
diff --git a/include/erebos/set.h b/include/erebos/set.h
new file mode 100644
index 0000000..f625cb0
--- /dev/null
+++ b/include/erebos/set.h
@@ -0,0 +1,96 @@
+#pragma once
+
+#include <erebos/merge.h>
+#include <erebos/storage.h>
+
+namespace erebos
+{
+
+class SetViewBase;
+template<class T> class SetView;
+
+class SetBase
+{
+protected:
+ struct Priv;
+
+ SetBase();
+ SetBase(const vector<Ref> &);
+ SetBase(shared_ptr<const Priv>);
+
+ shared_ptr<const Priv> add(Storage &, const vector<Ref> &) const;
+
+ vector<vector<Ref>> toList() const;
+
+public:
+ vector<Digest> digests() const;
+
+protected:
+ shared_ptr<const Priv> p;
+};
+
+template<class T>
+class Set : public SetBase
+{
+ Set(shared_ptr<const Priv> p): SetBase(p) {};
+public:
+ Set() = default;
+ Set(const vector<Ref> & refs): SetBase(move(refs)) {}
+ Set(const Set<T> &) = default;
+ Set(Set<T> &&) = default;
+ Set & operator=(const Set<T> &) = default;
+ Set & operator=(Set<T> &&) = default;
+
+ static Set<T> load(const vector<Ref> & refs) { return Set<T>(move(refs)); }
+
+ Set<T> add(Storage &, const T &) const;
+
+ template<class F>
+ SetView<T> view(F && cmp) const;
+};
+
+template<class T>
+class SetView
+{
+public:
+ template<class F>
+ SetView(F && cmp, const vector<vector<Ref>> & refs);
+
+ typename vector<T>::const_iterator begin() const { return items.begin(); }
+ typename vector<T>::const_iterator end() const { return items.end(); }
+
+private:
+ vector<T> items;
+};
+
+template<class T>
+Set<T> Set<T>::add(Storage & st, const T & x) const
+{
+ return Set<T>(SetBase::add(st, storedRefs(Mergeable<T>::components(x))));
+}
+
+template<class T>
+template<class F>
+SetView<T> Set<T>::view(F && cmp) const
+{
+ return SetView<T>(std::move(cmp), toList());
+}
+
+template<class T>
+template<class F>
+SetView<T>::SetView(F && cmp, const vector<vector<Ref>> & refs)
+{
+ items.reserve(refs.size());
+ for (const auto & crefs : refs) {
+ vector<Stored<typename Mergeable<T>::Component>> comps;
+ comps.reserve(crefs.size());
+ for (const auto & r : crefs)
+ comps.push_back(Stored<typename Mergeable<T>::Component>::load(r));
+
+ filterAncestors(comps);
+ items.push_back(Mergeable<T>::merge(comps));
+ }
+ std::sort(items.begin(), items.end(), cmp);
+}
+
+}
diff --git a/include/erebos/storage.h b/include/erebos/storage.h
index 15ee0bb..735b399 100644
--- a/include/erebos/storage.h
+++ b/include/erebos/storage.h
@@ -668,6 +668,16 @@ WatchedHead<T>::~WatchedHead()
T::headTypeId, Head<T>::id(), watcherId);
}
+template<class T>
+vector<Ref> storedRefs(const vector<Stored<T>> & v)
+{
+ vector<Ref> res;
+ res.reserve(v.size());
+ for (const auto & x : v)
+ res.push_back(x.ref());
+ return res;
+}
+
}
namespace std