From f5954d3cc6be8ab33ee16b2e6d78d09352f546e2 Mon Sep 17 00:00:00 2001 From: Seebs Date: Thu, 24 Feb 2022 14:59:40 -0600 Subject: [PATCH] use a pool for containerFilter objects We create a lot of these during a large GroupBy query or anything else that creates a ton of filters. Use a pool so we can reuse them, since most of their data doesn't need to be zeroed out, and typical use patterns have a lot of sequential creation of these short-lived things within a goroutine. --- rbf/tx.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/rbf/tx.go b/rbf/tx.go index 83ffe92e2..690937691 100644 --- a/rbf/tx.go +++ b/rbf/tx.go @@ -1258,6 +1258,22 @@ func (tx *Tx) ContainerIterator(name string, key uint64) (citer roaring.Containe return &containerIterator{cursor: c}, exact, nil } +// Shared pool for in-memory database pages. +// These are used before being flushed to disk. +var containerFilterPool = &sync.Pool{} + +func getContainerFilter(c *Cursor, filter roaring.BitmapFilter, tx *Tx) *containerFilter { + existing := containerFilterPool.Get() + if existing == nil { + return &containerFilter{cursor: c, filter: filter, tx: tx} + } + f := existing.(*containerFilter) + f.cursor = c + f.filter = filter + f.tx = tx + return f +} + func (tx *Tx) ApplyFilter(name string, key uint64, filter roaring.BitmapFilter) (err error) { tx.mu.RLock() defer tx.mu.RUnlock() @@ -1273,7 +1289,7 @@ func (tx *Tx) ApplyFilter(name string, key uint64, filter roaring.BitmapFilter) if err != nil { return err } - f := containerFilter{cursor: c, filter: filter, tx: tx} + f := getContainerFilter(c, filter, tx) defer f.Close() return f.Apply() } @@ -1615,6 +1631,8 @@ type containerFilter struct { func (s *containerFilter) Close() { s.cursor.Close() + s.cursor = nil + containerFilterPool.Put(s) } func (s *containerFilter) Apply() (err error) {