Packages
riptide
0.3.9
0.5.2
0.5.1
0.5.0-beta9
0.5.0-beta8
0.5.0-beta7
0.5.0-beta6
0.5.0-beta5
0.5.0-beta4
0.5.0-beta3
0.5.0-beta2
0.5.0-beta11
0.5.0-beta10
0.5.0-beta
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.3.0-bd63a38
0.2.79
0.2.78
0.2.74
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A data first framework for building realtime applications
Current section
Files
Jump to
Current section
Files
lib/riptide/store/store_memory.ex
defmodule Riptide.Store.Memory do
@moduledoc false
@behaviour Riptide.Store
def init(opts) do
opts
|> opts_table()
|> :ets.new([
:ordered_set,
:public,
:named_table,
read_concurrency: true,
write_concurrency: true
])
:ok
end
def opts_table(opts), do: Keyword.get(opts, :table, :riptide_table)
def mutation(merges, deletes, opts) do
table = opts_table(opts)
deletes
|> Enum.each(fn {path, _} ->
{last, rest} = List.pop_at(path, -1)
{min, max} = Riptide.Store.Prefix.range(last, %{})
min = rest ++ min
max = rest ++ max
table
|> iterate_keys(min, max)
|> Enum.each(fn path -> :ets.delete(table, path) end)
end)
:ets.insert(
table,
merges
|> Stream.map(fn {path, value} -> {path, Jason.encode!(value)} end)
|> Enum.to_list()
)
:ok
end
def query(paths, opts) do
table = opts_table(opts)
Stream.map(paths, fn {path, opts} -> {path, query_path(table, path, opts)} end)
end
def query_path(table, path, opts) do
{last, rest} = List.pop_at(path, -1)
{min, max} = Riptide.Store.Prefix.range(last, opts)
min = rest ++ min
max = rest ++ max
table
|> iterate_keys(min, max)
|> Stream.map(&:ets.lookup(table, &1))
|> Stream.map(&List.first/1)
|> Stream.filter(fn item -> item !== nil end)
|> Stream.map(fn {path, value} -> {path, Jason.decode!(value)} end)
end
def iterate_keys(table, min, max) do
Stream.resource(
fn -> :start end,
fn
:start ->
{[min], min}
key ->
case :ets.next(table, key) do
:"$end_of_table" -> {:halt, nil}
result when result >= max -> {:halt, nil}
result -> {[result], result}
end
end,
fn _ -> :skip end
)
end
end