···5566 alias Hobbes.Structs.RangeResult
7788+ @behaviour Hobbes.KV.Storage
99+810 @type t :: :ets.table
9111012 @spec new :: t
···1719 true = :ets.insert(kv, pairs)
1820 :ok
1921 end
2222+2323+ def commit(_kv), do: :ok
20242125 @spec put(:ets.table, binary, binary) :: :ok
2226 def put(kv, key, value) when is_binary(key) and is_binary(value) do
···3034 :ok
3135 end
32363333- @spec clear_range(:ets.table, binary, binary) :: :ok
3434- def clear_range(kv, start_key, end_key) when is_binary(start_key) and is_binary(end_key) do
3737+ @spec delete_range(:ets.table, binary, binary) :: :ok
3838+ def delete_range(kv, start_key, end_key) when is_binary(start_key) and is_binary(end_key) do
3539 :ets.select_delete(kv, [{
3640 {:"$1", :"$2"},
3741 [
···140144 :ets.delete_all_objects(kv)
141145 end
142146143143- @doc false
147147+ @spec dump(t) :: [{binary, binary}]
144148 def dump(kv) do
145149 :ets.tab2list(kv)
146150 end
+53
lib/kv/flat_storage_kv.ex
···11+defmodule Hobbes.KV.FlatStorageKV do
22+ alias Hobbes.Construct.SimFile
33+44+ alias Hobbes.KV.{FlatKV, FlatStorageKV}
55+66+ @behaviour Hobbes.KV.Storage
77+88+ @type t :: %__MODULE__{
99+ path: String.t,
1010+ kv: FlatKV.t,
1111+ }
1212+ @enforce_keys [:path, :kv]
1313+ defstruct @enforce_keys
1414+1515+ @spec new(String.t) :: t
1616+ def new(path) do
1717+ kv = %FlatStorageKV{path: path, kv: FlatKV.new()}
1818+1919+ case SimFile.read(path) do
2020+ {:ok, contents} ->
2121+ pairs = decode(contents)
2222+ FlatKV.load(kv.kv, pairs)
2323+2424+ {:error, :enoent} -> :noop
2525+ end
2626+2727+ kv
2828+ end
2929+3030+ def commit(%FlatStorageKV{kv: kv, path: path}) do
3131+ contents = FlatKV.dump(kv) |> encode()
3232+ :ok = SimFile.write(path, contents)
3333+ :ok
3434+ end
3535+3636+ def put(%{kv: kv}, key, value), do: FlatKV.put(kv, key, value)
3737+ def delete(%{kv: kv}, key), do: FlatKV.delete(kv, key)
3838+ def delete_range(%{kv: kv}, start_key, end_key), do: FlatKV.delete_range(kv, start_key, end_key)
3939+4040+ def get(%{kv: kv}, key), do: FlatKV.get(kv, key)
4141+ def scan(%{kv: kv}, start_key, end_key, opts \\ []), do: FlatKV.scan(kv, start_key, end_key, opts)
4242+4343+ defp encode(pairs) when is_list(pairs), do: :erlang.term_to_binary(pairs, [:deterministic])
4444+ defp decode(contents) when is_binary(contents), do: :erlang.binary_to_term(contents, [:safe])
4545+4646+ @doc false
4747+ def dump_file(%{path: path}) do
4848+ case SimFile.read(path) do
4949+ {:ok, contents} -> decode(contents)
5050+ {:error, _} -> nil
5151+ end
5252+ end
5353+end
+3-3
lib/servers/storage.ex
···103103 end
104104105105 def init(%{id: id, cluster: cluster}) do
106106- kv = HybridKV.new()
106106+ kv = HybridKV.new(path: "/#{Integer.to_string(id)}.storage_kv")
107107+107108 state = %State{
108109 id: id,
109110 cluster: cluster,
···274275275276 # Now that all shard clears are complete, we can flush the remaining versions
276277 HybridKV.flush(kv, flush_version)
277277-278278- # TODO: commit the storage changes here
278278+ HybridKV.commit(kv)
279279280280 # Send pops to tlogs
281281 # Note: pop is a cast (async) because the result doesn't matter for correctness
+5-5
test/kv/flat_kv_test.exs
···3030 end
3131 end
32323333- describe "clear_range/3" do
3333+ describe "delete_range/3" do
3434 setup %{kv: kv} do
3535 Enum.each(1..6, fn i ->
3636 :ok = FlatKV.put(kv, "foo#{i}", "bar#{i}")
···3939 end
40404141 test "clears at start", %{kv: kv} do
4242- assert :ok = FlatKV.clear_range(kv, "", "foo4")
4242+ assert :ok = FlatKV.delete_range(kv, "", "foo4")
4343 assert FlatKV.scan(kv, "", "zoo").pairs == [
4444 {"foo4", "bar4"},
4545 {"foo5", "bar5"},
···4848 end
49495050 test "clears at the end", %{kv: kv} do
5151- assert :ok = FlatKV.clear_range(kv, "foo4", "zoo")
5151+ assert :ok = FlatKV.delete_range(kv, "foo4", "zoo")
5252 assert FlatKV.scan(kv, "", "zoo").pairs == [
5353 {"foo1", "bar1"},
5454 {"foo2", "bar2"},
···5757 end
58585959 test "clears in the middle", %{kv: kv} do
6060- assert :ok = FlatKV.clear_range(kv, "foo3", "foo5")
6060+ assert :ok = FlatKV.delete_range(kv, "foo3", "foo5")
6161 assert FlatKV.scan(kv, "", "zoo").pairs == [
6262 {"foo1", "bar1"},
6363 {"foo2", "bar2"},
···6767 end
68686969 test "clears all", %{kv: kv} do
7070- assert :ok = FlatKV.clear_range(kv, "", "zoo")
7070+ assert :ok = FlatKV.delete_range(kv, "", "zoo")
7171 assert FlatKV.scan(kv, "", "zoo").pairs == []
7272 end
7373 end