Skip to content

Commit 7586bb2

Browse files
committed
changing bit indexing from 0-based to 1
1 parent 0bef750 commit 7586bb2

File tree

2 files changed

+205
-98
lines changed

2 files changed

+205
-98
lines changed

structures/patricia-trie/patricia-trie.go

Lines changed: 93 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import (
66
"github.com/disiqueira/gotree"
77
)
88

9+
func contains(a *PatriciaTrieNode, list []*PatriciaTrieNode) bool {
10+
for _, b := range list {
11+
if b == a {
12+
return true
13+
}
14+
}
15+
return false
16+
}
17+
918
type PatriciaTrieNode struct {
1019
key uint64
1120
bit_index uint
@@ -25,7 +34,7 @@ func (ptn *PatriciaTrieNode) String() string {
2534
}
2635

2736
func (ptn *PatriciaTrieNode) search(key uint64, prev_bi uint) bool {
28-
fmt.Printf("Search: \nCurrent node: %v\nprev_bi %v\nbit_index %v\n", ptn, prev_bi, ptn.bit_index)
37+
// fmt.Printf("Search: \nCurrent node: %v\nprev_bi %v\nbit_index %v\n", ptn, prev_bi, ptn.bit_index)
2938

3039
if prev_bi >= ptn.bit_index {
3140
return key == ptn.key
@@ -37,10 +46,10 @@ func (ptn *PatriciaTrieNode) search(key uint64, prev_bi uint) bool {
3746
}
3847
}
3948

40-
func (ptn *PatriciaTrieNode) find(key uint64, prev_bi uint) *PatriciaTrieNode {
49+
func (ptn *PatriciaTrieNode) find(key uint64, prev_bi uint) uint64 {
4150
// fmt.Printf("prev_bi %v, bit_index %v [%v]\n", prev_bi, ptn.bit_index, uint(prev_bi))
4251
if prev_bi >= ptn.bit_index {
43-
return ptn
52+
return ptn.key
4453
}
4554
if key&((1<<63)>>ptn.bit_index) == 0 {
4655
return ptn.left.find(key, ptn.bit_index)
@@ -49,68 +58,51 @@ func (ptn *PatriciaTrieNode) find(key uint64, prev_bi uint) *PatriciaTrieNode {
4958
}
5059
}
5160

52-
func (ptn *PatriciaTrieNode) insertNode(node, endNode, parentNode *PatriciaTrieNode) bool {
53-
// fmt.Printf("\n\n\nSTART\nParent Node: %v\nEnd Node: %v\nNode: %v\nCurrent Node: %v", parentNode, endNode, node, ptn)
54-
// if ptn.bit_index <= parentNode.bit_index {
55-
// return false
56-
// }
61+
func (ptn *PatriciaTrieNode) insertNode(node *PatriciaTrieNode, seenNodes []*PatriciaTrieNode) bool {
62+
5763
var nextNode *PatriciaTrieNode
5864
if node.key&((1<<63)>>ptn.bit_index) == 0 {
5965
nextNode = ptn.left
6066
} else {
6167
nextNode = ptn.right
6268
}
69+
fmt.Printf("\n\n\nSTART\nCurrent Node: %v\nNode: %v\nInsert node: %v\n\n\n", ptn, nextNode, node)
70+
6371
// if nextNode.bit_index < node.bit_index && ptn != endNode {
64-
if nextNode.bit_index < node.bit_index && parentNode.bit_index < ptn.bit_index {
65-
return nextNode.insertNode(node, endNode, ptn)
72+
// if nextNode.bit_index < node.bit_index && parentNode.bit_index < ptn.bit_index {
73+
if nextNode.bit_index < node.bit_index && !contains(nextNode, seenNodes) {
74+
75+
return nextNode.insertNode(node, append(seenNodes, ptn))
6676
} else {
6777
// if node.bit_index > ptn.bit_index {
6878
// parentNode = ptn
6979
// ptn = nextNode
7080
// }
7181
// fmt.Printf("\n\n\nParent Node: %v\nNext Node: %v\nNode: %v\nCurrent node: %v\n\n\n", parentNode, nextNode, node, ptn)
72-
if parentNode.right == ptn {
73-
parentNode.right = node
74-
} else if parentNode.left == ptn {
75-
parentNode.left = node
82+
fmt.Printf("\n\n\nCurrent Node: %v\nNode: %v\nInsert node: %v\n\n\n", ptn, nextNode, node)
83+
84+
if ptn.right == nextNode {
85+
ptn.right = node
86+
} else if ptn.left == nextNode {
87+
ptn.left = node
7688
} else {
7789
fmt.Println("ERROR: I am no son of my parent")
7890
return false
7991
}
8092

93+
fmt.Printf("Comparison: %b & %b = %b (bit index: %v)\n", node.key, uint64((1<<63)>>node.bit_index), node.key&((1<<63)>>node.bit_index), node.bit_index)
8194
if node.key&((1<<63)>>node.bit_index) == 0 {
8295
node.left = node
83-
node.right = ptn
96+
node.right = nextNode
8497
} else {
8598
node.right = node
86-
node.left = ptn
99+
node.left = nextNode
87100
}
88101
// fmt.Printf("Parent Node: %v\nNew Node: %v\n", parentNode, node)
89102
return true
90103
}
91104
}
92105

93-
// if prev_bi < ptn.bit_index {
94-
// return
95-
// }
96-
// if prev_bi > -1 && uint(prev_bi) >= ptn.bit_index {
97-
// fmt.Printf("Returning node: %p\n", ptn)
98-
// return ptn, nil
99-
// }
100-
// var parent, node *PatriciaTrieNode
101-
// if key&(1<<ptn.bit_index) == 0 {
102-
// node, parent = ptn.left.find(key, int(ptn.bit_index))
103-
// } else {
104-
// node, parent = ptn.right.find(key, int(ptn.bit_index))
105-
// }
106-
// if parent == nil {
107-
// parent = ptn
108-
// }
109-
// fmt.Printf("Returning parent: %p\n", ptn)
110-
// return node, parent
111-
//
112-
// }
113-
114106
func (ptn *PatriciaTrieNode) depth(accDepth int) int {
115107
fmt.Printf("right %v\nleft %v\nptn: %v\n", ptn.right, ptn.left, ptn)
116108
if !((ptn.right != nil && ptn.right.bit_index > ptn.bit_index) ||
@@ -130,31 +122,6 @@ func (ptn *PatriciaTrieNode) depth(accDepth int) int {
130122
return ld
131123
}
132124

133-
// func (ptn PatriciaTrieNode) toString(acc, prefix string) string {
134-
// if ptn.right == nil {
135-
// acc += fmt.Sprintf("-%v\n", ptn.key)
136-
// } else {
137-
// acc += fmt.Sprintf("-%v", ptn.key)
138-
// prefix += " |"
139-
// }
140-
// if ptn.left != nil {
141-
// acc += fmt.Sprintf("%v |", prefix)
142-
// ptn.left.toString(acc, prefix)
143-
// }
144-
// }
145-
146-
// func Print(ptn *PatriciaTrieNode, prefix string) {
147-
// fmt.Printf("- %v", ptn.key)
148-
// if ptn.right != nil {
149-
// Print(ptn.right, fmt.Sprintf("%v |", prefix))
150-
// } else {
151-
// fmt.Println()
152-
// fmt.Printf("%v |\n", prefix)
153-
// }
154-
// fmt.Printf("%v %v")
155-
//
156-
// }
157-
158125
func firstDiffBit(key1, key2 uint64) uint {
159126
var lBitPos uint = 63
160127
for ; lBitPos > 0 && (key1&(1<<lBitPos)) == (key2&(1<<lBitPos)); lBitPos-- {
@@ -211,15 +178,43 @@ func (pt *PatriciaTrie) Insert(key uint64) {
211178
// HEADER AND +1 NODES
212179

213180
fmt.Println("More than 2 nodes and key not present in trie")
214-
endNode := pt.header.left.find(key, 0)
215-
reachedKey := endNode.key
181+
reachedKey := pt.header.left.find(key, 0)
216182
lBitPos := firstDiffBit(key, reachedKey)
217183
node := &PatriciaTrieNode{key, lBitPos, nil, nil}
218184

219-
ok := pt.header.left.insertNode(node, endNode, pt.header)
220-
if !ok {
221-
fmt.Printf("ERROR: insertion of key %v was unsuccesful\n", key)
185+
// if node needs to be inserted after header do it manually
186+
if node.bit_index < pt.header.left.bit_index {
187+
fmt.Println("Insta inserting")
188+
fmt.Printf("Comparison: %b & %b = %b (bit index: %v)\n", node.key, uint64((1<<63)>>node.bit_index), node.key&((1<<63)>>node.bit_index), node.bit_index)
189+
190+
if node.key&((1<<63)>>node.bit_index) == 0 {
191+
node.left = node
192+
node.right = pt.header.left
193+
} else {
194+
node.right = node
195+
node.left = pt.header.left
196+
}
197+
fmt.Printf("Final header: %v -> %v, _\nNew node: %v -> %v, %v\n%v\n",
198+
pt.header.key, pt.header.left.key, node.key, node.left.key, node.right.key, pt.toString(false))
199+
// fmt.Printf("Final header: %v, %v\n",
200+
// pt.header.key, pt.header)
201+
// fmt.Printf("New node: %v -> %v, %v\n%v\n", pt.header.key, pt.header.left.key, pt.header.right.key, node.key, node.left.key, node.right.key, pt.toString(false))
202+
203+
fmt.Printf("%v\n", pt.toString(false))
204+
205+
pt.header.left = node
206+
fmt.Printf("Final header: %v -> %v, _\nNew node: %v -> %v, %v\n%v\n",
207+
pt.header.key, pt.header.left.key, node.key, node.left.key, node.right.key, pt.toString(false))
208+
209+
fmt.Printf("%v\n", pt.toString(false))
210+
211+
} else {
212+
ok := pt.header.left.insertNode(node, []*PatriciaTrieNode{pt.header})
213+
if !ok {
214+
fmt.Printf("ERROR: insertion of key %v was unsuccesful\n", key)
215+
}
222216
}
217+
223218
}
224219

225220
fmt.Printf("pt, %p\n", &pt)
@@ -233,47 +228,57 @@ func (pt *PatriciaTrie) Depth() int {
233228
return pt.header.depth(1)
234229
}
235230

236-
func (ptn *PatriciaTrieNode) populateTree(parent *gotree.Tree, dir string) {
237-
txt := fmt.Sprintf("%v %b[%v]", dir, ptn.key, ptn.bit_index)
231+
func (ptn *PatriciaTrieNode) populateTree(parent *gotree.Tree, dir string, binary bool) {
232+
var txt string
233+
if binary {
234+
txt = fmt.Sprintf("%v %b[%v]", dir, ptn.key, ptn.bit_index)
235+
} else {
236+
txt = fmt.Sprintf("%v %v[%v]", dir, ptn.key, ptn.bit_index)
237+
}
238238
if ptn.left != nil || ptn.right != nil {
239239
l := "_"
240240
r := "_"
241241
if ptn.left != nil {
242-
l = fmt.Sprintf("%b", ptn.left.key)
242+
if binary {
243+
l = fmt.Sprintf("%b", ptn.left.key)
244+
} else {
245+
l = fmt.Sprintf("%v", ptn.left.key)
246+
}
243247
}
244248
if ptn.right != nil {
245-
r = fmt.Sprintf("%b", ptn.right.key)
249+
if binary {
250+
l = fmt.Sprintf("%b", ptn.right.key)
251+
} else {
252+
l = fmt.Sprintf("%v", ptn.right.key)
253+
}
246254
}
247255
txt += fmt.Sprintf(" -> (%v, %v)", l, r)
248256
}
249257
node := (*parent).Add(txt)
250258
if ptn.left != nil && ptn.bit_index < ptn.left.bit_index {
251-
ptn.left.populateTree(&node, "L")
259+
ptn.left.populateTree(&node, "L", binary)
252260
}
253261
if ptn.right != nil && ptn.bit_index < ptn.right.bit_index {
254-
ptn.right.populateTree(&node, "R")
262+
ptn.right.populateTree(&node, "R", binary)
255263
}
256264
}
257265

258-
func print(ptn *PatriciaTrieNode) {
259-
if ptn != nil {
260-
if ptn.left != nil && ptn.bit_index < ptn.left.bit_index {
261-
print(ptn.left)
262-
}
263-
fmt.Printf("%v", ptn.key)
264-
if ptn.right != nil && ptn.bit_index < ptn.right.bit_index {
265-
print(ptn.right)
266-
}
267-
}
266+
func (pt *PatriciaTrie) String() string {
267+
268+
header := gotree.New("Header")
269+
270+
pt.header.populateTree(&header, "", true)
271+
272+
return header.Print()
273+
268274
}
269275

270-
func (pt *PatriciaTrie) Print() {
271-
// fmt.Printf("Header %v", pt.header)
272-
// print(pt.header)
276+
func (pt *PatriciaTrie) toString(binary bool) string {
277+
273278
header := gotree.New("Header")
274279

275-
pt.header.populateTree(&header, "")
280+
pt.header.populateTree(&header, "", binary)
276281

277-
fmt.Println(header.Print())
282+
return header.Print()
278283

279284
}

0 commit comments

Comments
 (0)