Skip to content

Commit b9547a3

Browse files
Merge pull request Workiva#172 from fasaxc/fix-ctrie-traverse
RM-19979 Fix that Ctrie iterator did not return entries from tNodes.
2 parents f456f73 + b4ec1df commit b9547a3

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

trie/ctrie/ctrie.go

+6
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,12 @@ func (c *Ctrie) traverse(i *iNode, ch chan<- *Entry, cancel <-chan struct{}) err
405405
return errCanceled
406406
}
407407
}
408+
case main.tNode != nil:
409+
select {
410+
case ch <- main.tNode.Entry:
411+
case <-cancel:
412+
return errCanceled
413+
}
408414
}
409415
return nil
410416
}

trie/ctrie/ctrie_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,24 @@ func TestIterator(t *testing.T) {
341341
assert.False(ok)
342342
}
343343

344+
// TestIteratorCoversTNodes reproduces the scenario of a bug where tNodes weren't being traversed.
345+
func TestIteratorCoversTNodes(t *testing.T) {
346+
assert := assert.New(t)
347+
ctrie := New(mockHashFactory)
348+
// Add a pair of keys that collide (because we're using the mock hash).
349+
ctrie.Insert([]byte("a"), true)
350+
ctrie.Insert([]byte("b"), true)
351+
// Delete one key, leaving exactly one sNode in the cNode. This will
352+
// trigger creation of a tNode.
353+
ctrie.Remove([]byte("b"))
354+
seenKeys := map[string]bool{}
355+
for entry := range ctrie.Iterator(nil) {
356+
seenKeys[string(entry.Key)] = true
357+
}
358+
assert.Contains(seenKeys, "a", "Iterator did not return 'a'.")
359+
assert.Len(seenKeys, 1)
360+
}
361+
344362
func TestSize(t *testing.T) {
345363
ctrie := New(nil)
346364
for i := 0; i < 10; i++ {

0 commit comments

Comments
 (0)