From 7d2ebce65465e2f62a39c32d1d778cf20de778ef Mon Sep 17 00:00:00 2001 From: Jussi Maki Date: Mon, 23 Feb 2026 14:58:56 +0100 Subject: [PATCH] part: Only reuse watches hash map when it is small This avoids carrying over a large allocation [txn.watches] from a massive one-off transaction into future transactions. This should mitigate https://github.com/cilium/cilium/issues/44310. Signed-off-by: Jussi Maki --- part/txn.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/part/txn.go b/part/txn.go index d7fa3ed..4b50949 100644 --- a/part/txn.go +++ b/part/txn.go @@ -199,6 +199,10 @@ func (txn *Txn[T]) Commit() Tree[T] { return t } +// watchesReuseThreshold is the threshold at which the [txn.watches] hash +// map is reused for next transaction. +const watchesReuseThreshold = 64 + // Notify closes the watch channels of nodes that were // mutated as part of this transaction. Must be called before // Tree.Txn() is used again. @@ -206,10 +210,15 @@ func (txn *Txn[T]) Notify() { for ch := range txn.watches { close(ch) } - clear(txn.watches) if !txn.dirty && len(txn.watches) > 0 { panic("BUG: watch channels marked but txn not dirty") } + // Clear or reallocate the watches hash map for the next transaction. + if len(txn.watches) <= watchesReuseThreshold { + clear(txn.watches) + } else { + txn.watches = make(map[chan struct{}]struct{}) + } if txn.dirty && txn.rootWatch != nil { close(txn.rootWatch) txn.rootWatch = nil