Current section
Files
Jump to
Current section
Files
lib/aatree.ex
# Generated by erl2ex (http://github.com/dazuma/erl2ex)
# From Erlang source: (Unknown source file)
# At: 2017-05-28 14:05:15
defmodule Aatree do
@typep aatree_node() :: nil | {any(), any(), any(), any()}
@opaque iter() :: list(aatree_node())
@opaque aatree() :: {non_neg_integer(), aatree_node()}
use Bitwise, only_operators: true
defmacrop erlconst_p() do
quote do
2
end
end
defmacrop erlmacro_pow(a, _) do
quote do
unquote(a) * unquote(a)
end
end
defmacrop erlmacro_div2(x) do
quote do
unquote(x) >>> 1
end
end
defmacrop erlmacro_mul2(x) do
quote do
unquote(x) <<< 1
end
end
@spec empty() :: aatree()
def empty() do
{0, nil}
end
@spec is_empty(tree) :: boolean() when tree: aatree()
def is_empty({0, nil}) do
true
end
def is_empty(_) do
false
end
@spec size(tree) :: non_neg_integer() when tree: aatree()
def size({var_size, _}) when is_integer(var_size) and var_size >= 0 do
var_size
end
@spec lookup(key, tree) :: :none | {:value, val} when key: term(), val: term(), tree: aatree()
def lookup(key, {_, t}) do
lookup_1(key, t)
end
defp lookup_1(key, {key1, _, smaller, _}) when key < key1 do
lookup_1(key, smaller)
end
defp lookup_1(key, {key1, _, _, bigger}) when key > key1 do
lookup_1(key, bigger)
end
defp lookup_1(_, {_, value, _, _}) do
{:value, value}
end
defp lookup_1(_, nil) do
:none
end
@spec is_defined(key, tree) :: boolean() when key: term(), tree: aatree()
def is_defined(key, {_, t}) do
is_defined_1(key, t)
end
defp is_defined_1(key, {key1, _, smaller, _}) when key < key1 do
is_defined_1(key, smaller)
end
defp is_defined_1(key, {key1, _, _, bigger}) when key > key1 do
is_defined_1(key, bigger)
end
defp is_defined_1(_, {_, _, _, _}) do
true
end
defp is_defined_1(_, nil) do
false
end
@spec get(key, tree) :: val when key: term(), tree: aatree(), val: term()
def get(key, {_, t}) do
get_1(key, t)
end
defp get_1(key, {key1, _, smaller, _}) when key < key1 do
get_1(key, smaller)
end
defp get_1(key, {key1, _, _, bigger}) when key > key1 do
get_1(key, bigger)
end
defp get_1(_, {_, value, _, _}) do
value
end
@spec update(key, val, tree1) :: tree2 when key: term(), val: term(), tree1: aatree(), tree2: aatree()
def update(key, val, {s, t}) do
t1 = update_1(key, val, t)
{s, t1}
end
defp update_1(key, value, {key1, v, smaller, bigger}) when key < key1 do
{key1, v, update_1(key, value, smaller), bigger}
end
defp update_1(key, value, {key1, v, smaller, bigger}) when key > key1 do
{key1, v, smaller, update_1(key, value, bigger)}
end
defp update_1(key, value, {_, _, smaller, bigger}) do
{key, value, smaller, bigger}
end
@spec insert(key, val, tree1) :: tree2 when key: term(), val: term(), tree1: aatree(), tree2: aatree()
def insert(key, val, {s, t}) when is_integer(s) do
s1 = s + 1
{s1, insert_1(key, val, t, erlmacro_pow(s1, erlconst_p()))}
end
defp insert_1(key, value, {key1, v, smaller, bigger}, s) when key < key1 do
case(insert_1(key, value, smaller, erlmacro_div2(s))) do
{t1, h1, s1} ->
t = {key1, v, t1, bigger}
{h2, s2} = count(bigger)
h = erlmacro_mul2(:erlang.max(h1, h2))
sS = s1 + s2 + 1
p = erlmacro_pow(sS, erlconst_p())
case(:if) do
:if when h > p ->
balance(t, sS)
:if when true ->
{t, h, sS}
end
t1 ->
{key1, v, t1, bigger}
end
end
defp insert_1(key, value, {key1, v, smaller, bigger}, s) when key > key1 do
case(insert_1(key, value, bigger, erlmacro_div2(s))) do
{t1, h1, s1} ->
t = {key1, v, smaller, t1}
{h2, s2} = count(smaller)
h = erlmacro_mul2(:erlang.max(h1, h2))
sS = s1 + s2 + 1
p = erlmacro_pow(sS, erlconst_p())
case(:if) do
:if when h > p ->
balance(t, sS)
:if when true ->
{t, h, sS}
end
t1 ->
{key1, v, smaller, t1}
end
end
defp insert_1(key, value, nil, s) when s === 0 do
{{key, value, nil, nil}, 1, 1}
end
defp insert_1(key, value, nil, _s) do
{key, value, nil, nil}
end
defp insert_1(key, _, _, _) do
:erlang.error({:key_exists, key})
end
@spec enter(key, val, tree1) :: tree2 when key: term(), val: term(), tree1: aatree(), tree2: aatree()
def enter(key, val, t) do
case(is_defined(key, t)) do
true ->
update(key, val, t)
false ->
insert(key, val, t)
end
end
def count({_, _, nil, nil}) do
{1, 1}
end
def count({_, _, sm, bi}) do
{h1, s1} = count(sm)
{h2, s2} = count(bi)
{erlmacro_mul2(:erlang.max(h1, h2)), s1 + s2 + 1}
end
def count(nil) do
{1, 0}
end
@spec balance(tree1) :: tree2 when tree1: aatree(), tree2: aatree()
def balance({s, t}) do
{s, balance(t, s)}
end
def balance(t, s) do
balance_list(to_list_1(t), s)
end
def balance_list(l, s) do
{t, []} = balance_list_1(l, s)
t
end
defp balance_list_1(l, s) when s > 1 do
sm = s - 1
s2 = div(sm, 2)
s1 = sm - s2
{t1, [{k, v} | l1]} = balance_list_1(l, s1)
{t2, l2} = balance_list_1(l1, s2)
t = {k, v, t1, t2}
{t, l2}
end
defp balance_list_1([{key, val} | l], 1) do
{{key, val, nil, nil}, l}
end
defp balance_list_1(l, 0) do
{nil, l}
end
@spec from_orddict(list) :: tree when list: list({term(), term()}), tree: aatree()
def from_orddict(l) do
s = length(l)
{s, balance_list(l, s)}
end
@spec delete_any(key, tree1) :: tree2 when key: term(), tree1: aatree(), tree2: aatree()
def delete_any(key, t) do
case(is_defined(key, t)) do
true ->
delete(key, t)
false ->
t
end
end
@spec delete(key, tree1) :: tree2 when key: term(), tree1: aatree(), tree2: aatree()
def delete(key, {s, t}) when is_integer(s) and s >= 0 do
{s - 1, delete_1(key, t)}
end
defp delete_1(key, {key1, value, smaller, larger}) when key < key1 do
smaller1 = delete_1(key, smaller)
{key1, value, smaller1, larger}
end
defp delete_1(key, {key1, value, smaller, bigger}) when key > key1 do
bigger1 = delete_1(key, bigger)
{key1, value, smaller, bigger1}
end
defp delete_1(_, {_, _, smaller, larger}) do
merge(smaller, larger)
end
def merge(smaller, nil) do
smaller
end
def merge(nil, larger) do
larger
end
def merge(smaller, larger) do
{key, value, larger1} = take_smallest_1(larger)
{key, value, smaller, larger1}
end
@spec take_smallest(tree1) :: {key, val, tree2} when tree1: aatree(), tree2: aatree(), key: term(), val: term()
def take_smallest({var_size, tree}) when is_integer(var_size) and var_size >= 0 do
{key, value, larger} = take_smallest_1(tree)
{key, value, {var_size - 1, larger}}
end
defp take_smallest_1({key, value, nil, larger}) do
{key, value, larger}
end
defp take_smallest_1({key, value, smaller, larger}) do
{key1, value1, smaller1} = take_smallest_1(smaller)
{key1, value1, {key, value, smaller1, larger}}
end
@spec smallest(tree) :: {key, val} when tree: aatree(), key: term(), val: term()
def smallest({_, tree}) do
smallest_1(tree)
end
defp smallest_1({key, value, nil, _larger}) do
{key, value}
end
defp smallest_1({_key, _value, smaller, _larger}) do
smallest_1(smaller)
end
@spec take_largest(tree1) :: {key, val, tree2} when tree1: aatree(), tree2: aatree(), key: term(), val: term()
def take_largest({var_size, tree}) when is_integer(var_size) and var_size >= 0 do
{key, value, smaller} = take_largest1(tree)
{key, value, {var_size - 1, smaller}}
end
defp take_largest1({key, value, smaller, nil}) do
{key, value, smaller}
end
defp take_largest1({key, value, smaller, larger}) do
{key1, value1, larger1} = take_largest1(larger)
{key1, value1, {key, value, smaller, larger1}}
end
@spec largest(tree) :: {key, val} when tree: aatree(), key: term(), val: term()
def largest({_, tree}) do
largest_1(tree)
end
defp largest_1({key, value, _smaller, nil}) do
{key, value}
end
defp largest_1({_key, _value, _smaller, larger}) do
largest_1(larger)
end
@spec to_list(tree) :: list({key, val}) when tree: aatree(), key: term(), val: term()
def to_list({_, t}) do
to_list(t, [])
end
defp to_list_1(t) do
to_list(t, [])
end
def to_list({key, value, small, big}, l) do
to_list(small, [{key, value} | to_list(big, l)])
end
def to_list(nil, l) do
l
end
@spec keys(tree) :: list(key) when tree: aatree(), key: term()
def keys({_, t}) do
keys(t, [])
end
def keys({key, _value, small, big}, l) do
keys(small, [key | keys(big, l)])
end
def keys(nil, l) do
l
end
@spec values(tree) :: list(val) when tree: aatree(), val: term()
def values({_, t}) do
values(t, [])
end
def values({_key, value, small, big}, l) do
values(small, [value | values(big, l)])
end
def values(nil, l) do
l
end
@spec iterator(tree) :: iter when tree: aatree(), iter: iter()
def iterator({_, t}) do
iterator_1(t)
end
def iterator_1(t) do
iterator(t, [])
end
def iterator({_, _, nil, _} = t, as) do
[t | as]
end
def iterator({_, _, l, _} = t, as) do
iterator(l, [t | as])
end
def iterator(nil, as) do
as
end
@spec next(iter1) :: :none | {key, val, iter2} when iter1: iter(), iter2: iter(), key: term(), val: term()
def next([{x, v, _, t} | as]) do
{x, v, iterator(t, as)}
end
def next([]) do
:none
end
@spec map(function, tree1) :: tree2 when function: (term(), term() -> term()), tree1: aatree(), tree2: aatree()
def map(f, {var_size, tree}) when is_function(f, 2) do
{var_size, map_1(f, tree)}
end
defp map_1(_, nil) do
nil
end
defp map_1(f, {k, v, smaller, larger}) do
{k, f.(k, v), map_1(f, smaller), map_1(f, larger)}
end
@spec to_string(tree) :: String.t when tree: aatree()
def to_string({size, tree}) do
"\n(size:" <> Integer.to_string(size) <> ")\n" <> do_to_string "", tree
end
def do_to_string(_, nil) do
"\n"
end
def do_to_string(pref, {k, v, smaller, larger}) do
"{ " <> Kernel.inspect(k) <> ", " <> Kernel.inspect(v) <> " }"
<> ")\n"
<> pref <> "+ " <> do_to_string((" " <> pref), smaller)
<> pref <> "+ " <> do_to_string((" " <> pref), larger)
end
# def nth({_,0}, _n) do
# nil
# end
# def nth({_,size}, n) when n > size - 1 do
# nil
# end
# def nth({r,size}, n) when n < 0 do
# do_nth(r, size + n)
# end
# def nth({r,_}, n) when n >= 0 do
# do_nth(r, n)
# end
# defp do_nth({_,h,k,v,l,r}, n) do
# l_count = left_count(h)
# cond do
# l_count > n && l == nil -> {k,v}
# l_count > n -> do_nth(l, n)
# l_count == n -> {k,v}
# r == nil -> {k,v}
# true -> do_nth(r, n - l_count - 1)
# end
# end
end