Permalink
Browse files

Merge branch 'release/1.0'

  • Loading branch information...
2 parents fb093a0 + 5fc6853 commit 0697e4d29b59143346cb988eeff1d75158547577 Andreas Hasselberg committed May 9, 2012
Showing with 48 additions and 11 deletions.
  1. +17 −0 README.md
  2. +1 −1 src/andylib.app.src
  3. +30 −10 src/avl.erl
View
@@ -0,0 +1,17 @@
+# AVL trees in erlang.
+
+This is an avl tree implementation in erlang. It has the same interface as gb_trees.
+Perfomance is better for sorted input but worse for random input.
+The worse performance on random input is due to the fact the avl trees has stricter balancing conditions.
+In a lot of cases where the avl get unbalanced and need balancing the gb_trees is ok and there is a sigificant chance that gb_trees will be more balanced after the next operation.
+The increased performace on ordered input is that the both trees need to balance a lot. The balancing of an avl tree takes less effort.
+
+## Todo
+### Complete
+ - Borrow type specs from gb_trees.
+ - Borrow interator and next.
+
+### Performance
+Would it improve performance to break the balancing of the tree when you know it's balanced?
+ - Tree hight didn't change above this level
+ - 2 balance has allready been made
View
@@ -1,7 +1,7 @@
{application, andylib,
[
{description, "Lots of very good modules"},
- {vsn, "0.1.0"},
+ {vsn, "1.0.0"},
{registered, []},
{applications, [
kernel,
View
@@ -16,15 +16,15 @@
delete/2, delete_any/2, balance/1,
keys/1, values/1, to_list/1, from_orddict/1,
smallest/1, largest/1, take_smallest/1, take_largest/1,
- enters/2, inserts/2
+ enters/2, inserts/2,
+ iterator/1, next/1
]).
-export([depth/1]).
+-ifdef(TEST).
-include_lib("proper/include/proper.hrl").
-
-%% iterator/1, next/1
-
+-endif.
%% node
%%
@@ -208,10 +208,20 @@ ops(Tree, List, F) ->
OpF = fun({Key, Val}, TreeAcc) -> F(Key, Val, TreeAcc) end,
lists:foldl(OpF, Tree, List).
+iterator(Tree) ->
+ iterator(Tree, []).
-%%TODO iterator
+%% Acc is the nodes with respective right branches yet to traverse.
+iterator({_Key, _Val, _Depth, ?nil, _TreeR} = T, Acc) -> %% no smaller element
+ [T|Acc];
+iterator({_Key, _Val, _Depth, TreeL, _TreeR} = T, Acc) -> %% walking down left
+ iterator(TreeL, [T|Acc]);
+iterator(?nil, Acc) -> Acc.
-%%TODO next
+next([{Key, Val, _Depth, _TreeL, TreeR} | As]) -> %% TreeL is allready consumed
+ {Key, Val, iterator(TreeR, As)};
+next([]) ->
+ none.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
@@ -220,11 +230,11 @@ is_ok(?nil) -> true;
is_ok({_, _, 1, ?nil, ?nil}) -> true;
is_ok({Key, _, 2, ?nil,
{KeyR, _, 1, ?nil, ?nil}}) ->
- true == (Key < KeyR);
+ Key < KeyR;
is_ok({Key, _, 2,
{KeyL, _, 1, ?nil, ?nil},
?nil}) ->
- true == (Key > KeyL);
+ Key > KeyL;
is_ok({Key, _, Depth, TreeL, TreeR}) ->
KeyL = element(1, TreeL),
KeyR = element(1, TreeR),
@@ -279,6 +289,7 @@ del_test() ->
?assertEqual([1, 5, 6, 7, 13], keys(delete(10, T))),
?assertEqual(["1", "5", "6", "7", "D"], values(delete(10, T))),
KeySort = lists:keysort(1, Stuff),
+ ?assertEqual(KeySort, iter_all(T)),
?assertEqual(KeySort, to_list(T)),
?assertEqual(T, from_orddict(KeySort)),
?assertEqual(?nil, from_orddict([])), %% silly
@@ -290,6 +301,15 @@ del_test() ->
?assert(is_ok(T)),
?assert(is_ok(T2)).
+iter_all(Tree) ->
+ iter_all(Tree, iterator(Tree)).
+
+iter_all(Tree, Iter) ->
+ case next(Iter) of
+ none -> [];
+ {Key, Val, NewIter} -> [{Key, Val}|iter_all(Tree, NewIter)]
+ end.
+
take_largest_test() ->
N = 15,
List0 = [ {X, random:uniform(N)} || X <- lists:seq(1, N) ],
@@ -317,15 +337,15 @@ proper_hack_test() ->
%% FIXME: do something more interesting of this.
prop_insert_get() ->
- ?FORALL(X, integer(),
+ ?FORALL(X, any(),
begin
Y = get(X, insert(X,X, empty())),
X =:= Y
end).
prop_gb() ->
?FORALL(List,
- list({integer(), integer()}),
+ list({any(), any()}),
begin
Tree = enters(empty(), List),
?assert(is_ok(Tree)),

0 comments on commit 0697e4d

Please sign in to comment.