Skip to content

Commit

Permalink
Free dedupe buffer's tracking map after shrink
Browse files Browse the repository at this point in the history
Go doesn't free map blocks, even after a map shrinks
considerably. The dedupe buffer tends to store a lot of
keys for a start-of-day snapshot, make sure we clean
up the leaked map capacity once we're back down to
zero.

Upstream issue: golang/go#20135
  • Loading branch information
fasaxc committed Nov 28, 2024
1 parent ddfc3b1 commit ab2eed4
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion libcalico-go/lib/backend/syncersv1/dedupebuffer/dedupe_buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ type DedupeBuffer struct {

// keyToPendingUpdate holds an entry for each updateWithStringKey in the
// pendingUpdates queue
keyToPendingUpdate map[string]*list.Element
keyToPendingUpdate map[string]*list.Element
peakPendingUpdatesLen int

// liveResourceKeys Contains an entry for every key that we have sent to
// the consumer and that we have not subsequently sent a deletion for.
liveResourceKeys set.Set[string]
Expand Down Expand Up @@ -176,6 +178,7 @@ func (d *DedupeBuffer) OnUpdatesKeysKnown(updates []api.Update, keys []string) {
update: u,
})
d.keyToPendingUpdate[key] = element
d.peakPendingUpdatesLen = max(len(d.keyToPendingUpdate), d.peakPendingUpdatesLen)
}
}
queueNowEmpty := d.pendingUpdates.Len() == 0
Expand Down Expand Up @@ -252,6 +255,14 @@ func (d *DedupeBuffer) pullNextBatch(buf []any, batchSize int) []any {
if u, ok := first.Value.(updateWithStringKey); ok {
key := u.key
delete(d.keyToPendingUpdate, key)
if len(d.keyToPendingUpdate) == 0 && d.peakPendingUpdatesLen > 100 {
// Map blocks never get freed when a map is scaled down.
// https://github.com/golang/go/issues/20135
// Opportunistically free the map when it's empty. This can
// free a good amount of RAM after loading a large snapshot.
d.keyToPendingUpdate = map[string]*list.Element{}
d.peakPendingUpdatesLen = 0
}
// Update liveResourceKeys now, before we drop the lock. Once we drop
// the lock we're committed to sending these keys.
if u.update.Value == nil {
Expand Down

0 comments on commit ab2eed4

Please sign in to comment.