Current section

Files

Jump to
datastructures lib data dictionary balanced_tree.ex
Raw

lib/data/dictionary/balanced_tree.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 Data.Dictionary.BalancedTree do
alias Data.Protocol, as: P
alias __MODULE__, as: T
defstruct dict: nil
def new do
%T{dict: :gb_trees.empty}
end
def new({ 0, nil } = self) do
%T{dict: self}
end
def new({ length, tree } = self) when is_integer(length) and is_tuple(tree) do
%T{dict: self}
end
def new(enum) do
%T{dict: Data.list(enum) |> :orddict.from_list |> :gb_trees.from_orddict}
end
def has_key?(%T{dict: self}, key) do
:gb_trees.is_defined(key, self)
end
def fetch(%T{dict: self}, key) do
case :gb_trees.lookup(key, self) do
{ :value, value } ->
{ :ok, value }
:none ->
:error
end
end
def put(%T{dict: self}, key, value) do
%T{dict: :gb_trees.enter(key, value, self)}
end
def put_new(%T{dict: self}, key, value) do
if :gb_trees.is_defined(key, self) do
%T{dict: self}
else
%T{dict: :gb_trees.insert(key, value, self)}
end
end
def delete(%T{dict: self}, key) do
%T{dict: :gb_trees.delete_any(key, self)}
end
def keys(%T{dict: self}) do
:gb_trees.keys(self)
end
def values(%T{dict: self}) do
:gb_trees.values(self)
end
def size(%T{dict: self}) do
:gb_trees.size(self)
end
def empty(_) do
:gb_trees.empty
end
def to_list(%T{dict: self}) do
:gb_trees.to_list(self)
end
def member?(%T{dict: self}, { key, value }) do
case :gb_trees.lookup(key, self) do
{ :value, ^value } ->
true
_ ->
false
end
end
def member?(%T{dict: self}, key) do
:gb_trees.is_defined(key, self)
end
defmodule Sequence do
defstruct [:iter]
def new(dict) do
%__MODULE__{iter: :gb_trees.iterator(dict)}
end
def first(%__MODULE__{iter: iter}) do
case :gb_trees.next(iter) do
:none ->
nil
{ key, value, _next } ->
{ key, value }
end
end
def next(%__MODULE__{iter: iter}) do
case :gb_trees.next(iter) do
:none ->
nil
{ _key, _value, next } ->
%__MODULE__{iter: next}
end
end
defimpl P.Sequence do
defdelegate first(self), to: Sequence
defdelegate next(self), to: Sequence
end
end
def to_sequence(%T{dict: self}) do
Sequence.new(self)
end
defimpl P.Dictionary do
defdelegate fetch(self, key), to: T
defdelegate put(self, key, value), to: T
defdelegate delete(self, key), to: T
defdelegate keys(self), to: T
defdelegate values(self), to: T
end
defimpl P.Count do
defdelegate count(self), to: T, as: :size
end
defimpl P.Empty do
def empty?(self) do
T.size(self) == 0
end
defdelegate clear(self), to: T, as: :empty
end
defimpl P.Reduce do
def reduce(self, acc, fun) do
Data.Seq.reduce(self, acc, fun)
end
end
defimpl P.ToList do
defdelegate to_list(self), to: T
end
defimpl P.Contains do
defdelegate contains?(self, key), to: T, as: :member?
end
defimpl P.ToSequence do
defdelegate to_sequence(self), to: T
end
defimpl P.Into do
def into(self, { key, value }) do
self |> T.put(key, value)
end
end
defimpl Enumerable do
use Data.Enumerable
end
defimpl Collectable do
use Data.Collectable
end
defimpl Inspect do
import Inspect.Algebra
def inspect(self, opts) do
concat ["#Dictionary<", to_doc(T.to_list(self), opts), ">"]
end
end
end