aboutsummaryrefslogtreecommitdiff
path: root/lib/data/store.ex
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2018-07-20 16:44:49 +0200
committerAlex Auvolat <alex@adnab.me>2018-07-20 16:53:08 +0200
commitc1dad415d42d0991f3c549c159d85b6146fb0768 (patch)
treed820851d282c85fa7079006c82c0ed212012a59c /lib/data/store.ex
parent87a35ab4741eaf78ec3eddc8c7452ef2a32477b7 (diff)
downloadshard-c1dad415d42d0991f3c549c159d85b6146fb0768.tar.gz
shard-c1dad415d42d0991f3c549c159d85b6146fb0768.zip
Use PageStore protocol
Diffstat (limited to 'lib/data/store.ex')
-rw-r--r--lib/data/store.ex91
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/data/store.ex b/lib/data/store.ex
new file mode 100644
index 0000000..ca12cd0
--- /dev/null
+++ b/lib/data/store.ex
@@ -0,0 +1,91 @@
+defprotocol SData.Page do
+ @moduledoc"""
+ Protocol to be implemented by objects that are used as data pages
+ in a pagestore and that may reference other data pages by their hash.
+ """
+
+ @fallback_to_any true
+
+ @doc"""
+ Get hashes of all pages referenced by this page.
+ """
+ def refs(page)
+end
+
+defimpl SData.Page, for: Any do
+ def refs(_page), do: []
+end
+
+
+defprotocol SData.PageStore do
+ @moduledoc"""
+ Protocol to be implemented for page stores to allow their
+ manipulation.
+
+ This protocol may also be implemented by store proxies that track
+ operations and implement different synchronization or caching mechanisms.
+ """
+
+ @doc"""
+ Put a page. Argument is the content of the page, returns the
+ hash that the store has associated to it.
+
+ Returns {hash, store}
+ """
+ def put(store, page)
+
+ @doc"""
+ Get a page referenced by its hash.
+
+ Returns page
+ """
+ def get(store, hash)
+
+ @doc"""
+ Copy to the store a page and all its references from the other store.
+ In the case of pages on the network in a distributed store, this may
+ be lazy.
+
+ Returns store
+ """
+ def copy(store, other_store, hash)
+
+ @doc"""
+ Free a page referenced by its hash, marking it as no longer needed.
+
+ Returns store
+ """
+ def free(store, hash)
+end
+
+
+defmodule SData.LocalStore do
+ defstruct [:pages]
+
+ def new() do
+ %SData.LocalStore{ pages: %{} }
+ end
+end
+
+defimpl SData.PageStore, for: SData.LocalStore do
+ def put(store, page) do
+ hash = SData.term_hash page
+ store = %{ store | pages: Map.put(store.pages, hash, page) }
+ { hash, store }
+ end
+
+ def get(store, hash) do
+ store.pages[hash]
+ end
+
+ def copy(store, other_store, hash) do
+ page = SData.PageStore.get(other_store, hash)
+ refs = SData.Page.refs(page)
+ store = Enum.reduce(refs, store, fn x, acc -> copy(acc, other_store, x) end)
+ %{ store | pages: Map.put(store.pages, hash, page) }
+ end
+
+ def free(store, hash) do
+ %{ store | pages: Map.delete(store.pages, hash) }
+ end
+end