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.
This commit is contained in:
Seebs 2022-02-24 14:59:40 -06:00
parent eb26a86518
commit f5954d3cc6

View file

@ -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) {