summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2021-04-27 22:59:52 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2021-05-08 13:23:34 +0200
commit567156b05183cc63aedbf57c03f26e0eaf43a39e (patch)
tree56e4ebf2199bd9539222515885f74856de82459c
parenta511d2d1ef5fa07dde601961fe9394b474aad5ae (diff)
SharedState type and lens
-rw-r--r--include/erebos/state.h31
-rw-r--r--src/state.cpp59
-rw-r--r--src/state.h20
3 files changed, 88 insertions, 22 deletions
diff --git a/include/erebos/state.h b/include/erebos/state.h
index 7060f22..cfa9532 100644
--- a/include/erebos/state.h
+++ b/include/erebos/state.h
@@ -8,6 +8,7 @@
namespace erebos {
using std::optional;
+using std::shared_ptr;
using std::vector;
class LocalState
@@ -42,6 +43,24 @@ private:
std::shared_ptr<Priv> p;
};
+class SharedState
+{
+public:
+ template<class T> optional<T> get() const;
+ template<typename T> static T lens(const SharedState &);
+
+ bool operator==(const SharedState &) const;
+ bool operator!=(const SharedState &) const;
+
+private:
+ vector<Ref> lookup(UUID) const;
+
+ struct Priv;
+ SharedState(shared_ptr<Priv> && p): p(std::move(p)) {}
+ shared_ptr<Priv> p;
+ friend class LocalState;
+};
+
template<class T>
optional<T> LocalState::shared() const
{
@@ -57,4 +76,16 @@ LocalState LocalState::shared(const vector<Stored<T>> & v) const
return updateShared(T::sharedTypeId, refs);
}
+template<class T>
+optional<T> SharedState::get() const
+{
+ return T::load(lookup(T::sharedTypeId));
+}
+
+template<class T>
+T SharedState::lens(const SharedState & x)
+{
+ return T::value_type::load(x.lookup(T::value_type::sharedTypeId));
+}
+
}
diff --git a/src/state.cpp b/src/state.cpp
index 1a3381a..82fe907 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -23,8 +23,8 @@ LocalState::LocalState(const Ref & ref):
p->identity = Identity::load(*x);
for (auto i : rec->items("shared"))
- if (const auto & x = i.as<SharedState>())
- p->shared.push_back(*x);
+ if (const auto & x = i.as<SharedData>())
+ p->shared.tip.push_back(*x);
}
Ref LocalState::store(const Storage & st) const
@@ -33,7 +33,7 @@ Ref LocalState::store(const Storage & st) const
if (p->identity)
items.emplace_back("id", *p->identity->ref());
- for (const auto & x : p->shared)
+ for (const auto & x : p->shared.tip)
items.emplace_back("shared", x);
return st.storeObject(Record(std::move(items)));
@@ -54,8 +54,18 @@ LocalState LocalState::identity(const Identity & id) const
vector<Ref> LocalState::lookupShared(UUID type) const
{
- vector<Stored<SharedState>> found;
- vector<Stored<SharedState>> process = p->shared;
+ return p->shared.lookup(type);
+}
+
+vector<Ref> SharedState::lookup(UUID type) const
+{
+ return p->lookup(type);
+}
+
+vector<Ref> SharedState::Priv::lookup(UUID type) const
+{
+ vector<Stored<SharedData>> found;
+ vector<Stored<SharedData>> process = tip;
while (!process.empty()) {
auto cur = std::move(process.back());
@@ -81,7 +91,7 @@ vector<Ref> LocalState::lookupShared(UUID type) const
vector<Ref> LocalState::sharedRefs() const
{
vector<Ref> refs;
- for (const auto & x : p->shared)
+ for (const auto & x : p->shared.tip)
refs.push_back(x.ref());
return refs;
}
@@ -89,8 +99,8 @@ vector<Ref> LocalState::sharedRefs() const
LocalState LocalState::sharedRefAdd(const Ref & ref) const
{
const Storage * st;
- if (p->shared.size() > 0)
- st = &p->shared[0].ref().storage();
+ if (p->shared.tip.size() > 0)
+ st = &p->shared.tip[0].ref().storage();
else if (p->identity)
st = &p->identity->ref()->storage();
else
@@ -99,16 +109,16 @@ LocalState LocalState::sharedRefAdd(const Ref & ref) const
LocalState ret;
ret.p->identity = p->identity;
ret.p->shared = p->shared;
- ret.p->shared.push_back(SharedState(ref).store(*st));
- filterAncestors(ret.p->shared);
+ ret.p->shared.tip.push_back(SharedData(ref).store(*st));
+ filterAncestors(ret.p->shared.tip);
return ret;
}
LocalState LocalState::updateShared(UUID type, const vector<Ref> & xs) const
{
const Storage * st;
- if (p->shared.size() > 0)
- st = &p->shared[0].ref().storage();
+ if (p->shared.tip.size() > 0)
+ st = &p->shared.tip[0].ref().storage();
else if (p->identity)
st = &p->identity->ref()->storage();
else if (xs.size() > 0)
@@ -118,19 +128,30 @@ LocalState LocalState::updateShared(UUID type, const vector<Ref> & xs) const
LocalState ret;
ret.p->identity = p->identity;
- ret.p->shared.push_back(SharedState(p->shared, type, xs).store(*st));
+ ret.p->shared.tip.push_back(SharedData(p->shared.tip, type, xs).store(*st));
return ret;
}
-SharedState::SharedState(const Ref & ref)
+bool SharedState::operator==(const SharedState & other) const
+{
+ return p->tip == other.p->tip;
+}
+
+bool SharedState::operator!=(const SharedState & other) const
+{
+ return p->tip != other.p->tip;
+}
+
+
+SharedData::SharedData(const Ref & ref)
{
auto rec = ref->asRecord();
if (!rec)
return;
for (auto i : rec->items("PREV"))
- if (const auto & x = i.as<SharedState>())
+ if (const auto & x = i.as<SharedData>())
prev.push_back(*x);
if (auto x = rec->item("type").asUUID())
@@ -141,7 +162,7 @@ SharedState::SharedState(const Ref & ref)
value.push_back(*x);
}
-Ref SharedState::store(const Storage & st) const
+Ref SharedData::store(const Storage & st) const
{
vector<Record::Item> items;
@@ -165,3 +186,9 @@ vector<Ref> LocalState::lens<vector<Ref>>(const LocalState & x)
{
return x.sharedRefs();
}
+
+template<>
+SharedState LocalState::lens<SharedState>(const LocalState & x)
+{
+ return SharedState(shared_ptr<SharedState::Priv>(x.p, &x.p->shared));
+}
diff --git a/src/state.h b/src/state.h
index d2c89fc..91dea94 100644
--- a/src/state.h
+++ b/src/state.h
@@ -5,26 +5,34 @@
#include "pubkey.h"
using std::optional;
+using std::shared_ptr;
using std::vector;
namespace erebos {
+struct SharedState::Priv
+{
+ vector<Ref> lookup(UUID) const;
+
+ vector<Stored<struct SharedData>> tip;
+};
+
struct LocalState::Priv
{
optional<Identity> identity;
- vector<Stored<struct SharedState>> shared;
+ SharedState::Priv shared;
};
-struct SharedState
+struct SharedData
{
- explicit SharedState(vector<Stored<SharedState>> prev,
+ explicit SharedData(vector<Stored<SharedData>> prev,
UUID type, vector<Ref> value):
prev(prev), type(type), value(value) {}
- explicit SharedState(const Ref &);
- static SharedState load(const Ref & ref) { return SharedState(ref); }
+ explicit SharedData(const Ref &);
+ static SharedData load(const Ref & ref) { return SharedData(ref); }
Ref store(const Storage &) const;
- vector<Stored<SharedState>> prev;
+ vector<Stored<SharedData>> prev;
UUID type;
vector<Ref> value;
};