Skip to content

Commit

Permalink
Fix kellydunn#5: Store complete key in leaf nodes.
Browse files Browse the repository at this point in the history
  • Loading branch information
nick-at-humin committed Oct 5, 2015
1 parent d3df51c commit 0b6c67e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
27 changes: 19 additions & 8 deletions art_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,21 @@ type ArtNode struct {
size uint8

// Leaf Node Attributes
key []byte
keySize uint64
value interface{}
nodeType uint8
key []byte
keySize uint64
completeKey []byte
value interface{}
nodeType uint8
}

func NewLeafNode(key []byte, value interface{}) *ArtNode {
func NewLeafNode(key, completeKey []byte, value interface{}) *ArtNode {
newKey := make([]byte, len(key))
copy(newKey, key)
l := &ArtNode{
key: newKey,
value: value,
nodeType: LEAF,
key: newKey,
completeKey: completeKey,
value: value,
nodeType: LEAF,
}

return l
Expand Down Expand Up @@ -647,6 +649,15 @@ func (n *ArtNode) copyMeta(other *ArtNode) {
n.prefixLen = other.prefixLen
}

// Key() returns the key used when the node was inserted
func (n *ArtNode) Key() interface{} {
if n.nodeType != LEAF {
return nil
}

return n.completeKey
}

// Returns the value of the given node, or nil if it is not a leaf.
func (n *ArtNode) Value() interface{} {
if n.nodeType != LEAF {
Expand Down
10 changes: 7 additions & 3 deletions art_node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ func TestShrink(t *testing.T) {
}

func TestNewLeafNode(t *testing.T) {
key := []byte{'a', 'r', 't' }
key := []byte{'a', 'r', 't'}
value := "tree"
l := NewLeafNode(key, value)
l := NewLeafNode(key, key, value)

if &l.key == &key {
t.Errorf("Address of key byte slices should not match.")
Expand All @@ -227,11 +227,15 @@ func TestNewLeafNode(t *testing.T) {
t.Errorf("Expected key value to match the one supplied")
}

if bytes.Compare(l.completeKey, key) != 0 {
t.Errorf("Expected completeKey value to match the one supplied")
}

if l.value != value {
t.Errorf("Expected initial value to match the one supplied")
}

if l.nodeType != LEAF {
t.Errorf("Expected Leaf node to be of LEAF type")
}
}
}
14 changes: 7 additions & 7 deletions art_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (t *ArtTree) searchHelper(current *ArtNode, key []byte, depth int) interfac
// Inserts the passed in value that is indexed by the passed in key into the ArtTree.
func (t *ArtTree) Insert(key []byte, value interface{}) {
key = ensureNullTerminatedKey(key)
t.insertHelper(t.root, &t.root, key, value, 0)
t.insertHelper(t.root, &t.root, key, key, value, 0)
}

// Recursive helper function that traverses the tree until an insertion point is found.
Expand All @@ -77,12 +77,12 @@ func (t *ArtTree) Insert(key []byte, value interface{}) {
//
// If there is no child at the specified key at the current depth of traversal, a new leaf node
// is created and inserted at this position.
func (t *ArtTree) insertHelper(current *ArtNode, currentRef **ArtNode, key []byte, value interface{}, depth int) {
func (t *ArtTree) insertHelper(current *ArtNode, currentRef **ArtNode, key, completeKey []byte, value interface{}, depth int) {
// @spec: Usually, the leaf can
// simply be inserted into an existing inner node, after growing
// it if necessary.
if current == nil {
*currentRef = NewLeafNode(key, value)
*currentRef = NewLeafNode(key, completeKey, value)
t.size += 1
return
}
Expand All @@ -100,7 +100,7 @@ func (t *ArtTree) insertHelper(current *ArtNode, currentRef **ArtNode, key []byt

// Create a new Inner Node to contain the new Leaf and the current node.
newNode4 := NewNode4()
newLeafNode := NewLeafNode(key, value)
newLeafNode := NewLeafNode(key, completeKey, value)

// Determine the longest common prefix between our current node and the key
limit := current.LongestCommonPrefix(newLeafNode, depth)
Expand Down Expand Up @@ -150,7 +150,7 @@ func (t *ArtTree) insertHelper(current *ArtNode, currentRef **ArtNode, key []byt
}

// Attach the desired insertion key
newLeafNode := NewLeafNode(key, value)
newLeafNode := NewLeafNode(key, completeKey, value)
newNode4.AddChild(key[depth+mismatch], newLeafNode)

t.size += 1
Expand All @@ -167,11 +167,11 @@ func (t *ArtTree) insertHelper(current *ArtNode, currentRef **ArtNode, key []byt
if *next != nil {

// Recurse, and keep looking for an insertion point
t.insertHelper(*next, next, key, value, depth+1)
t.insertHelper(*next, next, key, completeKey, value, depth+1)

} else {
// Otherwise, Add the child at the current position.
current.AddChild(key[depth], NewLeafNode(key, value))
current.AddChild(key[depth], NewLeafNode(key, completeKey, value))
t.size += 1
}
}
Expand Down

0 comments on commit 0b6c67e

Please sign in to comment.