Skip to content

Commit e1c45df

Browse files
author
Ricardo de Cillo
committed
Improve documentation and code organization
1 parent 4300564 commit e1c45df

File tree

1 file changed

+69
-73
lines changed

1 file changed

+69
-73
lines changed

lib/rrb_tree.ex

Lines changed: 69 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -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
290286
end

0 commit comments

Comments
 (0)