@@ -7,25 +7,23 @@ defmodule RrbTree do
77  # 
88  # A tree is consisted of one Root, many internal Nodes and Leaf nodes. 
99  """ 
10- 
1110  use  Bitwise ,  only_operators:  true 
1211
1312  alias  RrbTree.Node ,  as:  Node 
1413
15-   @ m  2  # Integer: tree branching exponent, as in 2^m. E.g, m = 2 so branching factor of 4. 
16- 
17-   @ b  ( 1  <<<  @ m ) 
18- 
19-   @ e  1  # Maximum extra steps on radix search miss 
14+   @ m  2            # Tree branching exponent, as in 2^m. E.g, m = 2 so branching factor of 4. 
15+   @ b  ( 1  <<<  @ m )   # Branching factor. The number of subtrees per node. 
16+   @ e  1            # Maximum extra steps on radix search miss 
2017
2118  defstruct  h:  1 ,    # the tree height. Leaf nodes have height = 1. 
2219            node:  % Node { } 
2320
21+   # Public: concatenates two trees. 
2422  def  concat ( % RrbTree { }  =  ltree ,  % RrbTree { }  =  rtree )  do 
2523    do_concat ( ltree . node ,  rtree . node ,  ltree . h ,  rtree . h ) 
2624  end 
2725
28-   # Given two subtrees , returns a balanced tree 
26+   # Internal:  Given a list of nodes , returns a balanced tree.  
2927  defp  make_tree ( nodes ,  h )  do 
3028    a  =  Enum . count ( nodes ) 
3129    p  =  Enum . reduce ( nodes ,  0 ,  fn  node ,  sum  ->  count_items ( node )  +  sum  end ) 
@@ -34,6 +32,7 @@ defmodule RrbTree do
3432    nodes  |>  balance ( extra_steps )  |>  root ( h ) 
3533  end 
3634
35+   # Internal: groups a list of nodes under a single root. Increase tree height when necessary. 
3736  defp  root ( nodes ,  h )  do 
3837    do_root ( nodes ,  % RrbTree { 
3938      h:  h , 
@@ -80,14 +79,7 @@ defmodule RrbTree do
8079    ) 
8180  end 
8281
83-   defp  last_range ( ranges )  when  tuple_size ( ranges )  ==  0  do 
84-     0 
85-   end 
86- 
87-   defp  last_range ( ranges )  do 
88-     last ( ranges ) 
89-   end 
90- 
82+   # Internal: given a list of nodes, rebalance then until the maximum extra steps reach the @e criteria. 
9183  defp  balance ( nodes ,  extra_steps )  do 
9284    balance ( nodes ,  extra_steps ,  [ ] ) 
9385  end 
@@ -128,6 +120,7 @@ defmodule RrbTree do
128120  end 
129121
130122  # TODO: Node only 
123+   # Internal: pushes into the left node as many slots as possible from the right. 
131124  defp  join_nodes ( n1  =  % Node { slots:  n1_slots } ,  n2  =  % Node { slots:  n2_slots } )  when  tuple_size ( n1_slots )  ==  @ b  or  tuple_size ( n2_slots )  ==  0  do 
132125    [ n1 ,  n2 ] 
133126  end 
@@ -159,29 +152,14 @@ defmodule RrbTree do
159152    ) 
160153  end 
161154
162-   defp  count_items ( % Node { }  =  node )  do 
163-     tuple_size ( node . slots ) 
164-   end 
165- 
166-   defp  count_items ( leaf )  do 
167-     tuple_size ( leaf ) 
168-   end 
169- 
170155  defp  do_concat ( % Node { }  =  ltree ,  % Node { }  =  rtree ,  _hl  =  2 ,  _hr  =  2 )  do 
171156    make_tree ( Tuple . to_list ( ltree . slots )  ++  Tuple . to_list ( rtree . slots ) ,  2 ) 
172157  end 
173158
174159  defp  do_concat ( % Node { }  =  ltree ,  % Node { }  =  rtree ,  hl ,  hr )  when  hl  ==  hr  do 
175160    mtree  =  do_concat ( rhand ( ltree ) ,  lhand ( rtree ) ,  hl  -  1 ,  hr  -  1 ) 
176161
177-     # TODO: check correctness when mtree.h > ltree.h OR mtree.h > rtree.h 
178-     if  mtree . h  ==  hl  do 
179-       # IO.puts "mtree.h > hl #{inspect mtree}" 
180-       make_tree ( Tuple . to_list ( lbody ( ltree ) . slots )  ++  Tuple . to_list ( mtree . node . slots )  ++  Tuple . to_list ( rbody ( rtree ) . slots ) ,  hl ) 
181-     else 
182-       # IO.puts "else \nlbody #{inspect(lbody(ltree))}\n mtree #{inspect(mtree)} \n rbody #{inspect(rbody(rtree))}" 
183-       # make_tree([lbody(ltree), mtree.node, rbody(rtree)], hl) 
184-     end 
162+     make_tree ( Tuple . to_list ( lbody ( ltree ) . slots )  ++  Tuple . to_list ( mtree . node . slots )  ++  Tuple . to_list ( rbody ( rtree ) . slots ) ,  hl ) 
185163  end 
186164
187165  defp  do_concat ( % Node { }  =  ltree ,  % Node { }  =  rtree ,  hl ,  hr )  when  hl  >  hr  do 
@@ -196,48 +174,6 @@ defmodule RrbTree do
196174    make_tree ( Tuple . to_list ( mtree . node . slots )  ++  Tuple . to_list ( rbody ( rtree ) . slots ) ,  hr ) 
197175  end 
198176
199-   defp  rhand ( % Node { }  =  node )  do 
200-     last ( node . slots ) 
201-   end 
202- 
203-   defp  lhand ( % Node { }  =  node )  do 
204-     first ( node . slots ) 
205-   end 
206- 
207-   defp  lbody ( % Node { ranges:  ranges ,  slots:  slots } )  do 
208-     % Node { 
209-       ranges:  Tuple . delete_at ( ranges ,  tuple_size ( ranges )  -  1 ) , 
210-       slots:  Tuple . delete_at ( slots ,  tuple_size ( slots )  -  1 ) 
211-     } 
212-   end 
213- 
214-   defp  rbody ( % Node { ranges:  ranges ,  slots:  slots } )  do 
215-     % Node { 
216-       ranges:  delete_first_range ( ranges ) , 
217-       slots:  Tuple . delete_at ( slots ,  0 ) 
218-     } 
219-   end 
220- 
221-   defp  delete_first_range ( ranges )  do 
222-     fst  =  elem ( ranges ,  0 ) 
223- 
224-     Tuple . delete_at ( ranges ,  0 ) 
225-       |>  Tuple . to_list 
226-       |>  Enum . reduce ( { } ,  fn ( r ,  rs )  ->  append ( rs ,  r  -  fst )  end ) 
227-   end 
228- 
229-   defp  first ( tuple )  do 
230-     elem ( tuple ,  0 ) 
231-   end 
232- 
233-   defp  last ( tuple )  do 
234-     elem ( tuple ,  tuple_size ( tuple )  -  1 ) 
235-   end 
236- 
237-   defp  append ( tuple ,  e )  do 
238-     Tuple . insert_at ( tuple ,  tuple_size ( tuple ) ,  e ) 
239-   end 
240- 
241177  def  get ( % RrbTree { }  =  t ,  index )  do 
242178    do_get ( t . h ,  t . node ,  index ) 
243179  end 
@@ -287,4 +223,64 @@ defmodule RrbTree do
287223      i  -  elem ( ranges ,  branch_index  -  1 ) 
288224    end 
289225  end 
226+ 
227+   # Utils: functions with low abstraction importance, just to DRY code. 
228+ 
229+   defp  last_range ( ranges )  when  tuple_size ( ranges )  ==  0  do 
230+     0 
231+   end 
232+ 
233+   defp  last_range ( ranges )  do 
234+     last ( ranges ) 
235+   end 
236+ 
237+   defp  count_items ( % Node { }  =  node )  do 
238+     tuple_size ( node . slots ) 
239+   end 
240+ 
241+   defp  count_items ( leaf )  do 
242+     tuple_size ( leaf ) 
243+   end 
244+ 
245+   defp  rhand ( % Node { }  =  node )  do 
246+     last ( node . slots ) 
247+   end 
248+ 
249+   defp  lhand ( % Node { }  =  node )  do 
250+     first ( node . slots ) 
251+   end 
252+ 
253+   defp  lbody ( % Node { ranges:  ranges ,  slots:  slots } )  do 
254+     % Node { 
255+       ranges:  Tuple . delete_at ( ranges ,  tuple_size ( ranges )  -  1 ) , 
256+       slots:  Tuple . delete_at ( slots ,  tuple_size ( slots )  -  1 ) 
257+     } 
258+   end 
259+ 
260+   defp  rbody ( % Node { ranges:  ranges ,  slots:  slots } )  do 
261+     % Node { 
262+       ranges:  delete_first_range ( ranges ) , 
263+       slots:  Tuple . delete_at ( slots ,  0 ) 
264+     } 
265+   end 
266+ 
267+   defp  delete_first_range ( ranges )  do 
268+     fst  =  elem ( ranges ,  0 ) 
269+ 
270+     Tuple . delete_at ( ranges ,  0 ) 
271+       |>  Tuple . to_list 
272+       |>  Enum . reduce ( { } ,  fn ( r ,  rs )  ->  append ( rs ,  r  -  fst )  end ) 
273+   end 
274+ 
275+   defp  first ( tuple )  do 
276+     elem ( tuple ,  0 ) 
277+   end 
278+ 
279+   defp  last ( tuple )  do 
280+     elem ( tuple ,  tuple_size ( tuple )  -  1 ) 
281+   end 
282+ 
283+   defp  append ( tuple ,  e )  do 
284+     Tuple . insert_at ( tuple ,  tuple_size ( tuple ) ,  e ) 
285+   end 
290286end 
0 commit comments