Commit 8b25ab89 authored by Petar Maymounkov's avatar Petar Maymounkov

Make XorTrie fields public.

parent 96a5b4b6
...@@ -14,24 +14,24 @@ func add(depth int, trie *XorTrie, q key.Key) *XorTrie { ...@@ -14,24 +14,24 @@ func add(depth int, trie *XorTrie, q key.Key) *XorTrie {
dir := q.BitAt(depth) dir := q.BitAt(depth)
if !trie.isLeaf() { if !trie.isLeaf() {
s := &XorTrie{} s := &XorTrie{}
s.branch[dir] = add(depth+1, trie.branch[dir], q) s.Branch[dir] = add(depth+1, trie.Branch[dir], q)
s.branch[1-dir] = trie.branch[1-dir] s.Branch[1-dir] = trie.Branch[1-dir]
return s return s
} else { } else {
if trie.key == nil { if trie.Key == nil {
return &XorTrie{key: q} return &XorTrie{Key: q}
} else { } else {
if key.Equal(trie.key, q) { if key.Equal(trie.Key, q) {
return trie return trie
} else { } else {
s := &XorTrie{} s := &XorTrie{}
if q.BitAt(depth) == trie.key.BitAt(depth) { if q.BitAt(depth) == trie.Key.BitAt(depth) {
s.branch[dir] = add(depth+1, &XorTrie{key: trie.key}, q) s.Branch[dir] = add(depth+1, &XorTrie{Key: trie.Key}, q)
s.branch[1-dir] = &XorTrie{} s.Branch[1-dir] = &XorTrie{}
return s return s
} else { } else {
s.branch[dir] = add(depth+1, &XorTrie{key: trie.key}, q) s.Branch[dir] = add(depth+1, &XorTrie{Key: trie.Key}, q)
s.branch[1-dir] = &XorTrie{} s.Branch[1-dir] = &XorTrie{}
} }
return s return s
} }
......
...@@ -7,9 +7,9 @@ import ( ...@@ -7,9 +7,9 @@ import (
func Equal(p, q *XorTrie) bool { func Equal(p, q *XorTrie) bool {
switch { switch {
case p.isLeaf() && q.isLeaf(): case p.isLeaf() && q.isLeaf():
return key.Equal(p.key, q.key) return key.Equal(p.Key, q.Key)
case !p.isLeaf() && !q.isLeaf(): case !p.isLeaf() && !q.isLeaf():
return Equal(p.branch[0], q.branch[0]) && Equal(p.branch[1], q.branch[1]) return Equal(p.Branch[0], q.Branch[0]) && Equal(p.Branch[1], q.Branch[1])
} }
return false return false
} }
...@@ -16,8 +16,8 @@ func intersect(depth int, p, q *XorTrie) *XorTrie { ...@@ -16,8 +16,8 @@ func intersect(depth int, p, q *XorTrie) *XorTrie {
if p.isEmpty() || q.isEmpty() { if p.isEmpty() || q.isEmpty() {
return &XorTrie{} // empty set return &XorTrie{} // empty set
} else { } else {
if key.Equal(p.key, q.key) { if key.Equal(p.Key, q.Key) {
return &XorTrie{key: p.key} // singleton return &XorTrie{Key: p.Key} // singleton
} else { } else {
return &XorTrie{} // empty set return &XorTrie{} // empty set
} }
...@@ -26,8 +26,8 @@ func intersect(depth int, p, q *XorTrie) *XorTrie { ...@@ -26,8 +26,8 @@ func intersect(depth int, p, q *XorTrie) *XorTrie {
if p.isEmpty() { if p.isEmpty() {
return &XorTrie{} // empty set return &XorTrie{} // empty set
} else { } else {
if _, found := q.find(depth, p.key); found { if _, found := q.find(depth, p.Key); found {
return &XorTrie{key: p.key} return &XorTrie{Key: p.Key}
} else { } else {
return &XorTrie{} // empty set return &XorTrie{} // empty set
} }
...@@ -36,9 +36,9 @@ func intersect(depth int, p, q *XorTrie) *XorTrie { ...@@ -36,9 +36,9 @@ func intersect(depth int, p, q *XorTrie) *XorTrie {
return Intersect(q, p) return Intersect(q, p)
case !p.isLeaf() && !q.isLeaf(): case !p.isLeaf() && !q.isLeaf():
disjointUnion := &XorTrie{ disjointUnion := &XorTrie{
branch: [2]*XorTrie{ Branch: [2]*XorTrie{
intersect(depth+1, p.branch[0], q.branch[0]), intersect(depth+1, p.Branch[0], q.Branch[0]),
intersect(depth+1, p.branch[1], q.branch[1]), intersect(depth+1, p.Branch[1], q.Branch[1]),
}, },
} }
disjointUnion.shrink() disjointUnion.shrink()
......
...@@ -7,10 +7,11 @@ import ( ...@@ -7,10 +7,11 @@ import (
// XorTrie is a trie for equal-length bit vectors, which stores values only in the leaves. // XorTrie is a trie for equal-length bit vectors, which stores values only in the leaves.
// XorTrie node invariants: // XorTrie node invariants:
// (1) Either both branches are nil, or both are non-nil. // (1) Either both branches are nil, or both are non-nil.
// (2) If both branches are leaves, then they are both non-empty (have keys). // (2) If branches are non-nil, key must be nil.
// (3) If both branches are leaves, then they are both non-empty (have keys).
type XorTrie struct { type XorTrie struct {
branch [2]*XorTrie Branch [2]*XorTrie
key key.Key Key key.Key
} }
func New() *XorTrie { func New() *XorTrie {
...@@ -22,10 +23,10 @@ func (trie *XorTrie) Depth() int { ...@@ -22,10 +23,10 @@ func (trie *XorTrie) Depth() int {
} }
func (trie *XorTrie) depth(depth int) int { func (trie *XorTrie) depth(depth int) int {
if trie.branch[0] == nil && trie.branch[1] == nil { if trie.Branch[0] == nil && trie.Branch[1] == nil {
return depth return depth
} else { } else {
return max(trie.branch[0].depth(depth+1), trie.branch[1].depth(depth+1)) return max(trie.Branch[0].depth(depth+1), trie.Branch[1].depth(depth+1))
} }
} }
...@@ -41,13 +42,13 @@ func (trie *XorTrie) Find(q key.Key) (reachedDepth int, found bool) { ...@@ -41,13 +42,13 @@ func (trie *XorTrie) Find(q key.Key) (reachedDepth int, found bool) {
} }
func (trie *XorTrie) find(depth int, q key.Key) (reachedDepth int, found bool) { func (trie *XorTrie) find(depth int, q key.Key) (reachedDepth int, found bool) {
if qb := trie.branch[q.BitAt(depth)]; qb != nil { if qb := trie.Branch[q.BitAt(depth)]; qb != nil {
return qb.find(depth+1, q) return qb.find(depth+1, q)
} else { } else {
if trie.key == nil { if trie.Key == nil {
return depth, false return depth, false
} else { } else {
return depth, key.Equal(trie.key, q) return depth, key.Equal(trie.Key, q)
} }
} }
} }
...@@ -59,22 +60,22 @@ func (trie *XorTrie) Add(q key.Key) (insertedDepth int, insertedOK bool) { ...@@ -59,22 +60,22 @@ func (trie *XorTrie) Add(q key.Key) (insertedDepth int, insertedOK bool) {
} }
func (trie *XorTrie) add(depth int, q key.Key) (insertedDepth int, insertedOK bool) { func (trie *XorTrie) add(depth int, q key.Key) (insertedDepth int, insertedOK bool) {
if qb := trie.branch[q.BitAt(depth)]; qb != nil { if qb := trie.Branch[q.BitAt(depth)]; qb != nil {
return qb.add(depth+1, q) return qb.add(depth+1, q)
} else { } else {
if trie.key == nil { if trie.Key == nil {
trie.key = q trie.Key = q
return depth, true return depth, true
} else { } else {
if key.Equal(trie.key, q) { if key.Equal(trie.Key, q) {
return depth, false return depth, false
} else { } else {
p := trie.key p := trie.Key
trie.key = nil trie.Key = nil
// both branches are nil // both Branches are nil
trie.branch[0], trie.branch[1] = &XorTrie{}, &XorTrie{} trie.Branch[0], trie.Branch[1] = &XorTrie{}, &XorTrie{}
trie.branch[p.BitAt(depth)].add(depth+1, p) trie.Branch[p.BitAt(depth)].add(depth+1, p)
return trie.branch[q.BitAt(depth)].add(depth+1, q) return trie.Branch[q.BitAt(depth)].add(depth+1, q)
} }
} }
} }
...@@ -87,7 +88,7 @@ func (trie *XorTrie) Remove(q key.Key) (removedDepth int, removed bool) { ...@@ -87,7 +88,7 @@ func (trie *XorTrie) Remove(q key.Key) (removedDepth int, removed bool) {
} }
func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed bool) { func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed bool) {
if qb := trie.branch[q.BitAt(depth)]; qb != nil { if qb := trie.Branch[q.BitAt(depth)]; qb != nil {
if d, ok := qb.remove(depth+1, q); ok { if d, ok := qb.remove(depth+1, q); ok {
trie.shrink() trie.shrink()
return d, true return d, true
...@@ -95,8 +96,8 @@ func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed boo ...@@ -95,8 +96,8 @@ func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed boo
return d, false return d, false
} }
} else { } else {
if trie.key != nil && key.Equal(q, trie.key) { if trie.Key != nil && key.Equal(q, trie.Key) {
trie.key = nil trie.Key = nil
return depth, true return depth, true
} else { } else {
return depth, false return depth, false
...@@ -105,11 +106,11 @@ func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed boo ...@@ -105,11 +106,11 @@ func (trie *XorTrie) remove(depth int, q key.Key) (reachedDepth int, removed boo
} }
func (trie *XorTrie) isEmpty() bool { func (trie *XorTrie) isEmpty() bool {
return trie.key == nil return trie.Key == nil
} }
func (trie *XorTrie) isLeaf() bool { func (trie *XorTrie) isLeaf() bool {
return trie.branch[0] == nil && trie.branch[1] == nil return trie.Branch[0] == nil && trie.Branch[1] == nil
} }
func (trie *XorTrie) isEmptyLeaf() bool { func (trie *XorTrie) isEmptyLeaf() bool {
...@@ -121,15 +122,15 @@ func (trie *XorTrie) isNonEmptyLeaf() bool { ...@@ -121,15 +122,15 @@ func (trie *XorTrie) isNonEmptyLeaf() bool {
} }
func (trie *XorTrie) shrink() { func (trie *XorTrie) shrink() {
b0, b1 := trie.branch[0], trie.branch[1] b0, b1 := trie.Branch[0], trie.Branch[1]
switch { switch {
case b0.isEmptyLeaf() && b1.isEmptyLeaf(): case b0.isEmptyLeaf() && b1.isEmptyLeaf():
trie.branch[0], trie.branch[1] = nil, nil trie.Branch[0], trie.Branch[1] = nil, nil
case b0.isEmptyLeaf() && b1.isNonEmptyLeaf(): case b0.isEmptyLeaf() && b1.isNonEmptyLeaf():
trie.key = b1.key trie.Key = b1.Key
trie.branch[0], trie.branch[1] = nil, nil trie.Branch[0], trie.Branch[1] = nil, nil
case b0.isNonEmptyLeaf() && b1.isEmptyLeaf(): case b0.isNonEmptyLeaf() && b1.isEmptyLeaf():
trie.key = b0.key trie.Key = b0.Key
trie.branch[0], trie.branch[1] = nil, nil trie.Branch[0], trie.Branch[1] = nil, nil
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment