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