From b38f48b6420f25a6edb30d73b7a175e644b93ea1 Mon Sep 17 00:00:00 2001 From: Radu Berinde Date: Mon, 22 Jul 2024 11:23:46 -0700 Subject: [PATCH] sstable: use sync.Pool for interval block collectors --- iterator_test.go | 3 +++ sstable/block_property.go | 20 +++++++++++++++++++- sstable/block_property_obsolete.go | 3 +++ sstable/block_property_test.go | 3 +++ sstable/writer.go | 10 ++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/iterator_test.go b/iterator_test.go index fc4fc09bbe..e4b306fa03 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -280,6 +280,9 @@ func (c *minSeqNumPropertyCollector) SupportsSuffixReplacement() bool { return false } +// Close is part of the BlockPropertyCollector interface. +func (c *minSeqNumPropertyCollector) Close() {} + // minSeqNumFilter is a BlockPropertyFilter that uses the // minSeqNumPropertyCollector data to filter out entire tables. type minSeqNumFilter struct { diff --git a/sstable/block_property.go b/sstable/block_property.go index 40a9f5ec04..59349ad0fc 100644 --- a/sstable/block_property.go +++ b/sstable/block_property.go @@ -131,6 +131,10 @@ type BlockPropertyCollector interface { // Finish appends the property value to buf and resets the collector to an // empty state. Finish(buf []byte) []byte + + // Close can be used to allow the implementation to be reused in the future. + // Once Close is called, the object must no longer be used. + Close() } // BlockPropertyFilter is used in an Iterator to filter sstables and blocks @@ -250,11 +254,19 @@ func NewBlockIntervalCollector( if mapper == nil { panic("mapper must be provided") } - return &BlockIntervalCollector{ + c := blockIntervalCollectorPool.Get().(*BlockIntervalCollector) + *c = BlockIntervalCollector{ name: name, mapper: mapper, suffixReplacer: suffixReplacer, } + return c +} + +var blockIntervalCollectorPool = sync.Pool{ + New: func() interface{} { + return &BlockIntervalCollector{} + }, } // Name is part of the BlockPropertyCollector interface. @@ -328,6 +340,12 @@ func (b *BlockIntervalCollector) Finish(buf []byte) []byte { return result } +// Close is part of the BlockPropertyCollector interface. +func (b *BlockIntervalCollector) Close() { + *b = BlockIntervalCollector{} + blockIntervalCollectorPool.Put(b) +} + // BlockInterval represents the [Lower, Upper) interval of 64-bit values // corresponding to a set of keys. The meaning of the values themselves is // opaque to the BlockIntervalCollector. diff --git a/sstable/block_property_obsolete.go b/sstable/block_property_obsolete.go index ef11dc3395..4dd57ef560 100644 --- a/sstable/block_property_obsolete.go +++ b/sstable/block_property_obsolete.go @@ -50,6 +50,9 @@ func (o *obsoleteKeyBlockPropertyCollector) Finish(buf []byte) []byte { return res } +// Close is part of the BlockPropertyCollector interface. +func (o *obsoleteKeyBlockPropertyCollector) Close() {} + // AddCollected is part of the BlockPropertyCollector interface. func (o *obsoleteKeyBlockPropertyCollector) AddCollected(oldProp []byte) error { isObsolete, err := obsoleteKeyBlockPropertyDecode(oldProp) diff --git a/sstable/block_property_test.go b/sstable/block_property_test.go index e60878705b..9c4ba89a57 100644 --- a/sstable/block_property_test.go +++ b/sstable/block_property_test.go @@ -1369,6 +1369,9 @@ func (p *keyCountCollector) SupportsSuffixReplacement() bool { return true } +// Close is part of the BlockPropertyCollector interface. +func (p *keyCountCollector) Close() {} + type intSuffixIntervalMapper struct { suffixLen int } diff --git a/sstable/writer.go b/sstable/writer.go index a779e3f9a4..a68a27ae63 100644 --- a/sstable/writer.go +++ b/sstable/writer.go @@ -2091,6 +2091,16 @@ func (w *Writer) Close() (err error) { indexBlockBufPool.Put(w.indexBlock) w.indexBlock = nil + // Close property collectors. Closing is optional, we don't need to do it in + // error paths. + for _, p := range w.blockPropCollectors { + p.dataBlock.Close() + p.indexBlock.Close() + p.rangeKeyBlock.Close() + p.table.Close() + } + w.blockPropCollectors = nil + // Make any future calls to Set or Close return an error. w.err = errWriterClosed return nil