Current section

Files

Jump to
nuamnesia lib amnesia table stream.ex
Raw

lib/amnesia/table/stream.ex

# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
defmodule Amnesia.Table.Stream do
defstruct table: nil, type: nil, lock: :read, dirty: false, reverse: false
alias __MODULE__, as: S
def new(name, type, options) do
lock = Keyword.get(options, :lock, :read)
dirty = Keyword.get(options, :dirty, false)
reverse = Keyword.get(options, :reverse, false)
stream = %S{table: name, type: type, lock: lock, dirty: dirty, reverse: reverse}
if first(stream) do
stream
else
[]
end
end
defp first(%S{table: table, dirty: false, reverse: false}) do
table.first(true)
end
defp first(%S{table: table, dirty: false, reverse: true}) do
table.last(true)
end
defp first(%S{table: table, dirty: true, reverse: false}) do
table.first!(true)
end
defp first(%S{table: table, dirty: true, reverse: true}) do
table.last!(true)
end
defp next(%S{table: table, dirty: false, reverse: false}, key) do
table.next(key)
end
defp next(%S{table: table, dirty: false, reverse: true}, key) do
table.prev(key)
end
defp next(%S{table: table, dirty: true, reverse: false}, key) do
table.next!(key)
end
defp next(%S{table: table, dirty: true, reverse: true}, key) do
table.prev!(key)
end
defp read(%S{table: table, dirty: false}, key) do
table.read(key)
end
defp read(%S{table: table, dirty: true}, key) do
table.read!(key)
end
@doc """
Reverse the stream.
"""
def reverse(%S{reverse: reverse} = self) do
%S{self | reverse: not reverse}
end
@doc false
def reduce(stream, acc, fun) do
reduce(stream, first(stream), acc, fun)
end
defp reduce(_stream, _key, { :halt, acc }, _fun) do
{ :halted, acc }
end
defp reduce(stream, key, { :suspend, acc }, fun) do
{ :suspended, acc, &reduce(stream, key, &1, fun) }
end
defp reduce(_stream, nil, { :cont, acc }, _fun) do
{ :done, acc }
end
defp reduce(stream, key, { :cont, acc }, fun) do
reduce(stream, next(stream, key), fun.(read(stream, key), acc), fun)
end
defimpl Enumerable do
def reduce(stream, acc, fun) do
Amnesia.Table.Stream.reduce(stream, acc, fun)
end
def count(_) do
{ :error, __MODULE__ }
end
def member?(_, _) do
{ :error, __MODULE__ }
end
def slice(_) do
{ :error, __MODULE__ }
end
end
end