Skip to content

Commit 89159c2

Browse files
fix(provider): memory usage (#1163)
* fix(provider): lower memory usage * minor optimizations
1 parent 6e9a59c commit 89159c2

1 file changed

Lines changed: 34 additions & 29 deletions

File tree

provider/internal/keyspace/trie.go

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"github.com/probe-lab/go-libdht/kad/trie"
1414
)
1515

16+
var zeroKey = bit256.ZeroKey()
17+
1618
// AllEntries returns all entries (key + value) stored in the trie `t` sorted
1719
// by their keys in the supplied `order`.
1820
func AllEntries[K0 kad.Key[K0], K1 kad.Key[K1], D any](t *trie.Trie[K0, D], order K1) []*trie.Entry[K0, D] {
@@ -313,48 +315,51 @@ func AllocateToKClosest[K kad.Key[K], V0 any, V1 comparable](items *trie.Trie[K,
313315
//
314316
// Returns a map of destination values to their allocated items.
315317
func allocateToKClosestAtDepth[K kad.Key[K], V0 any, V1 comparable](items *trie.Trie[K, V0], dests *trie.Trie[K, V1], k, depth int) map[V1][]V0 {
316-
m := make(map[V1][]V0)
317318
if k == 0 {
318-
return m
319+
return nil
320+
}
321+
destBranches := []*trie.Trie[K, V1]{
322+
dests.Branch(0),
323+
dests.Branch(1),
324+
}
325+
destValues := [][]V1{
326+
AllValues(dests.Branch(0), zeroKey),
327+
AllValues(dests.Branch(1), zeroKey),
319328
}
320-
for i := range 2 {
329+
if dests.IsLeaf() {
330+
if !dests.HasKey() {
331+
return nil
332+
}
333+
b := int((*dests.Key()).Bit(depth))
334+
destValues[b] = []V1{dests.Data()}
335+
destValues[1-b] = nil
336+
destBranches[b] = dests
337+
destBranches[1-b] = nil
338+
}
339+
m := make(map[V1][]V0, len(destValues[0])+len(destValues[1]))
340+
for i := range destValues {
321341
// Assign all items from branch i
322342

343+
matchingDestsBranch := destBranches[i]
344+
otherDestsBranch := destBranches[1-i]
345+
matchingDests := destValues[i]
346+
otherDests := destValues[1-i]
347+
323348
matchingItemsBranch := items.Branch(i)
324-
matchingItems := AllValues(matchingItemsBranch, bit256.ZeroKey())
325-
if len(matchingItems) == 0 {
349+
if matchingItemsBranch == nil || matchingItemsBranch.IsEmptyLeaf() {
350+
// No matching items
326351
if !items.IsNonEmptyLeaf() || int((*items.Key()).Bit(depth)) != i {
327352
// items' current branch is empty, skip it
328353
continue
329354
}
330355
// items' current branch contains a single leaf
331-
matchingItems = []V0{items.Data()}
332356
matchingItemsBranch = items
333357
}
334-
335-
matchingDestsBranch := dests.Branch(i)
336-
otherDestsBranch := dests.Branch(1 - i)
337-
matchingDests := AllValues(matchingDestsBranch, bit256.ZeroKey())
338-
otherDests := AllValues(otherDestsBranch, bit256.ZeroKey())
339-
if dests.IsLeaf() {
340-
// Single key (leaf) in dests
341-
if dests.IsNonEmptyLeaf() {
342-
if int((*dests.Key()).Bit(depth)) == i {
343-
// Leaf matches current branch
344-
matchingDests = []V1{dests.Data()}
345-
matchingDestsBranch = dests
346-
} else {
347-
// Leaf matches other branch
348-
otherDests = []V1{dests.Data()}
349-
otherDestsBranch = dests
350-
}
351-
} else {
352-
// Empty leaf, no dests to allocate items.
353-
return m
354-
}
355-
}
356-
357358
if nMatchingDests := len(matchingDests); nMatchingDests <= k {
359+
matchingItems := AllValues(matchingItemsBranch, zeroKey)
360+
if len(matchingItems) == 0 {
361+
matchingItems = []V0{items.Data()}
362+
}
358363
// Allocate matching items to the matching dests branch
359364
for _, dest := range matchingDests {
360365
m[dest] = append(m[dest], matchingItems...)

0 commit comments

Comments
 (0)