Skip to content

Commit af1dcbf

Browse files
author
Ricardo de Cillo
committed
Paper concatenation example implemented successfuly
1 parent f5f470e commit af1dcbf

File tree

2 files changed

+110
-10
lines changed

2 files changed

+110
-10
lines changed

lib/rrb_tree.ex

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ defmodule RrbTree do
3131
p = Enum.reduce(nodes, 0, fn node, sum -> count_items(node) + sum end)
3232
extra_steps = a - ((p - 1) >>> @m) - 1
3333

34+
#IO.puts "extra steps #{extra_steps}"
35+
3436
nodes |> balance(extra_steps) |> root(h)
3537
end
3638

@@ -100,36 +102,66 @@ defmodule RrbTree do
100102
balance(xs, e, [x | result])
101103
end
102104

103-
def balance([%Node{slots: slots} | xs], extra_steps, result) when tuple_size(slots) == 0 do
104-
balance(xs, extra_steps - 1, result)
105+
def balance([x1 = %Node{}, x2 = %Node{slots: slots} | xs], extra_steps, result) when tuple_size(slots) == 0 do
106+
balance(xs, extra_steps - 1, [x1 | result])
105107
end
106108

107-
def balance([x1 = %Node{slots: slots}, x2 | xs], _extra_steps, result) when tuple_size(slots) == @b do
108-
balance([x2 | xs], @e, [x1 | result])
109+
def balance([x1 = %Node{slots: slots}, x2 | xs], extra_steps, result) when tuple_size(slots) == @b do
110+
balance([x2 | xs], extra_steps, [x1 | result])
109111
end
110112

111113
def balance([x1 = %Node{slots: slots}, x2 | xs], extra_steps, result) when tuple_size(slots) < @b do
112114
[x1, x2] = join_nodes(x1, x2)
113-
balance([x1, x2 | xs], extra_steps - 1, result)
115+
balance([x1, x2 | xs], extra_steps, result)
116+
end
117+
118+
# TODO: Tuple only duplication
119+
# def balance([slots | xs], extra_steps, result) when tuple_size(slots) == 0 do
120+
# balance(xs, extra_steps - 1, result)
121+
# end
122+
def balance([x1, x2 | xs], e, result) when tuple_size(x2) == 0 do
123+
balance(xs, e - 1, [x1 | result])
124+
end
125+
126+
def balance([x1, x2 | xs], e, result) when tuple_size(x1) == @b do
127+
balance([x2 | xs], e, [x1 | result])
114128
end
115129

130+
def balance([x1, x2 | xs], extra_steps, result) when tuple_size(x1) < @b do
131+
[x1, x2] = join_nodes(x1, x2)
132+
balance([x1, x2 | xs], extra_steps, result)
133+
end
134+
135+
# TODO: Node only
116136
def 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
117137
[n1, n2]
118138
end
119139

120140
# TODO: try not to generate many nodes untill have a full node
121141
# TODO: handle leafs differently then internal nodes
122-
def join_nodes(n1, n2) do
123-
[
142+
def join_nodes(n1 = %Node{}, n2 = %Node{}) do
143+
join_nodes(
124144
%Node{
125145
ranges: Tuple.insert_at(n1.ranges, tuple_size(n1.ranges), elem(n2.ranges, tuple_size(n2.ranges) - 1) + elem(n1.ranges, tuple_size(n1.ranges) - 1)),
126146
slots: Tuple.insert_at(n1.slots, tuple_size(n1.slots), elem(n2.slots, 0))
127147
},
128148
%Node{
129-
ranges: Tuple.delete_at(n2.ranges, 0),
149+
ranges: delete_first_range(n2.ranges),
130150
slots: Tuple.delete_at(n2.slots, 0)
131151
}
132-
]
152+
)
153+
end
154+
155+
# TODO: Leaf only
156+
def join_nodes(n1, n2) when tuple_size(n1) == @b or tuple_size(n2) == 0 do
157+
[n1, n2]
158+
end
159+
160+
def join_nodes(n1, n2) do
161+
join_nodes(
162+
append(n1, elem(n2, 0)),
163+
Tuple.delete_at(n2, 0)
164+
)
133165
end
134166

135167
def count_items(%Node{} = node) do
@@ -153,7 +185,7 @@ defmodule RrbTree do
153185
make_tree(Tuple.to_list(lbody(ltree).slots) ++ Tuple.to_list(mtree.node.slots) ++ Tuple.to_list(rbody(rtree).slots), hl)
154186
else
155187
# IO.puts "else \nlbody #{inspect(lbody(ltree))}\n mtree #{inspect(mtree)} \n rbody #{inspect(rbody(rtree))}"
156-
make_tree([lbody(ltree), mtree.node, rbody(rtree)], hl)
188+
# make_tree([lbody(ltree), mtree.node, rbody(rtree)], hl)
157189
end
158190
end
159191

test/rrb_tree_test.exs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,72 @@ defmodule RrbTreeTest do
137137

138138
assert RrbTree.concat(t3, t3) == t
139139
end
140+
141+
test "paper figure 7 example" do
142+
t1 = %RrbTree{h: 2,
143+
node: %Node{
144+
ranges: {3, 7, 10, 14},
145+
slots: {
146+
{1, 2, 3},
147+
{4, 5, 6, 7},
148+
{8, 9, 10},
149+
{11, 12, 13, 14}
150+
}
151+
}
152+
}
153+
154+
t2 = %RrbTree{h: 2,
155+
node: %Node{
156+
ranges: {4, 6},
157+
slots: {
158+
{1, 2, 3, 4},
159+
{5, 6}
160+
}
161+
}
162+
}
163+
164+
t3 = %RrbTree{h: 2,
165+
node: %Node{
166+
ranges: {3, 5, 7, 10},
167+
slots: {
168+
{1, 2, 3},
169+
{4, 5},
170+
{6, 7},
171+
{8, 9 , 10}
172+
}
173+
}
174+
}
175+
176+
t4 = %RrbTree{h: 2,
177+
node: %Node{
178+
ranges: {3, 7},
179+
slots: {
180+
{1, 2, 3},
181+
{4, 5, 6, 7}
182+
}
183+
}
184+
}
185+
186+
t1_2 = %RrbTree{h: 3,
187+
node: %Node{
188+
ranges: {14, 20},
189+
slots: {t1.node, t2.node}
190+
}
191+
}
192+
193+
t3_4 = %RrbTree{h: 3,
194+
node: %Node{
195+
ranges: {10, 17},
196+
slots: {t3.node, t4.node}
197+
}
198+
}
199+
200+
t = %RrbTree{h: 3,
201+
node: %RrbTree.Node{ranges: {14, 27, 30, 37},
202+
slots: {%RrbTree.Node{ranges: {3, 7, 10, 14}, slots: {{1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10}, {11, 12, 13, 14}}},
203+
%RrbTree.Node{ranges: {4, 8, 11, 13}, slots: {{1, 2, 3, 4}, {5, 6, 1, 2}, {3, 4, 5}, {6, 7}}}, %RrbTree.Node{ranges: {3}, slots: {{8, 9, 10}}},
204+
%RrbTree.Node{ranges: {3, 7}, slots: {{1, 2, 3}, {4, 5, 6, 7}}}}}}
205+
206+
assert RrbTree.concat(t1_2, t3_4) == t
207+
end
140208
end

0 commit comments

Comments
 (0)