fixed collectChildNames

This commit is contained in:
Brannon King 2021-08-07 08:53:12 -04:00 committed by Roy Lee
parent 1a3f34c345
commit 3c0e288e0f
2 changed files with 38 additions and 13 deletions

View file

@ -187,7 +187,6 @@ func collectChildNames(changes []change.Change) {
// we need to determine which children (names that start with the same name) go with which change // we need to determine which children (names that start with the same name) go with which change
// if we have the names in order then we can avoid iterating through all names in the change list // if we have the names in order then we can avoid iterating through all names in the change list
// and we can possibly reuse the previous list. // and we can possibly reuse the previous list.
// eh. optimize it some other day
// what would happen in the old code: // what would happen in the old code:
// spending a claim (which happens before every update) could remove a node from the cached trie // spending a claim (which happens before every update) could remove a node from the cached trie
@ -213,9 +212,6 @@ func collectChildNames(changes []change.Change) {
spends = append(spends, pair{string(changes[i].Name), i}) spends = append(spends, pair{string(changes[i].Name), i})
} }
sort.Slice(spends, func(i, j int) bool { sort.Slice(spends, func(i, j int) bool {
if spends[i].name == spends[j].name {
return spends[i].order < spends[j].order
}
return spends[i].name < spends[j].name return spends[i].name < spends[j].name
}) })
@ -226,15 +222,16 @@ func collectChildNames(changes []change.Change) {
} }
a := string(changes[i].Name) a := string(changes[i].Name)
sc := map[string]bool{} sc := map[string]bool{}
idx := sort.Search(len(spends), func(i int) bool { idx := sort.Search(len(spends), func(k int) bool {
return spends[i].name >= a return spends[k].name > a
}) })
for idx < len(spends) { for idx < len(spends) {
b := spends[idx].name b := spends[idx].name
if len(b) >= len(a) && spends[idx].order < i && a == b[:len(a)] { if len(b) <= len(a) || a != b[:len(a)] {
break // since they're ordered alphabetically, we should be able to break out once we're past matches
}
if spends[idx].order < i {
sc[b] = true sc[b] = true
} else {
break
} }
idx++ idx++
} }
@ -242,6 +239,29 @@ func collectChildNames(changes []change.Change) {
} }
} }
// to understand the above function, it may be helpful to refer to the slower implementation:
//func collectChildNamesSlow(changes []change.Change) {
// for i := range changes {
// t := changes[i].Type
// if t == change.SpendClaim || t == change.SpendSupport {
// continue
// }
// a := changes[i].Name
// sc := map[string]bool{}
// for j := 0; j < i; j++ {
// t = changes[j].Type
// if t != change.SpendClaim {
// continue
// }
// b := changes[j].Name
// if len(b) >= len(a) && bytes.Equal(a, b[:len(a)]) {
// sc[string(b)] = true
// }
// }
// changes[i].SpentChildren = sc
// }
//}
func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) { func (nm *BaseManager) IncrementHeightTo(height int32) ([][]byte, error) {
if height <= nm.height { if height <= nm.height {

View file

@ -236,16 +236,21 @@ func TestCollectChildren(t *testing.T) {
c4 := change.Change{Name: []byte("ac"), Type: change.UpdateClaim} c4 := change.Change{Name: []byte("ac"), Type: change.UpdateClaim}
c5 := change.Change{Name: []byte("a"), Type: change.SpendClaim} c5 := change.Change{Name: []byte("a"), Type: change.SpendClaim}
c6 := change.Change{Name: []byte("a"), Type: change.UpdateClaim} c6 := change.Change{Name: []byte("a"), Type: change.UpdateClaim}
c := []change.Change{c1, c2, c3, c4, c5, c6} c7 := change.Change{Name: []byte("ab"), Type: change.SpendClaim}
c8 := change.Change{Name: []byte("ab"), Type: change.UpdateClaim}
c := []change.Change{c1, c2, c3, c4, c5, c6, c7, c8}
collectChildNames(c) collectChildNames(c)
r.Empty(c[0].SpentChildren) r.Empty(c[0].SpentChildren)
r.Empty(c[2].SpentChildren) r.Empty(c[2].SpentChildren)
r.Empty(c[4].SpentChildren) r.Empty(c[4].SpentChildren)
r.Empty(c[6].SpentChildren)
r.Len(c[1].SpentChildren, 1) r.Len(c[1].SpentChildren, 0)
r.Len(c[3].SpentChildren, 1) r.Len(c[3].SpentChildren, 0)
r.Len(c[5].SpentChildren, 2) r.Len(c[5].SpentChildren, 1)
r.True(c[5].SpentChildren["ac"]) r.True(c[5].SpentChildren["ac"])
r.Len(c[7].SpentChildren, 0)
} }