summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-09 14:35:41 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-12 16:16:53 -0700
commitfd89ca3095fc93f503d0cff6e0c380b2b67502f4 (patch)
tree1b5fce5ff5a33e55594f056a7e0e70881b7e4c27 /lib
parentd91f8ce17a6fc165fafd9dc921911233a69c34d2 (diff)
diskio: BufferedFile: Add a buffer pool to avoid allocations
Diffstat (limited to 'lib')
-rw-r--r--lib/diskio/file_blockbuf.go16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/diskio/file_blockbuf.go b/lib/diskio/file_blockbuf.go
index 15ae13b..3db3105 100644
--- a/lib/diskio/file_blockbuf.go
+++ b/lib/diskio/file_blockbuf.go
@@ -7,6 +7,8 @@ package diskio
import (
"sync"
+ "git.lukeshu.com/go/typedsync"
+
"git.lukeshu.com/btrfs-progs-ng/lib/containers"
)
@@ -20,18 +22,28 @@ type bufferedFile[A ~int64] struct {
mu sync.RWMutex
blockSize A
blockCache containers.ARCache[A, bufferedBlock]
+ blockPool typedsync.Pool[[]byte]
}
var _ File[assertAddr] = (*bufferedFile[assertAddr])(nil)
func NewBufferedFile[A ~int64](file File[A], blockSize A, cacheSize int) *bufferedFile[A] {
- return &bufferedFile[A]{
+ ret := &bufferedFile[A]{
inner: file,
blockSize: blockSize,
blockCache: containers.ARCache[A, bufferedBlock]{
MaxLen: cacheSize,
},
+ blockPool: typedsync.Pool[[]byte]{
+ New: func() []byte {
+ return make([]byte, blockSize)
+ },
+ },
+ }
+ ret.blockCache.OnRemove = func(_ A, buf bufferedBlock) {
+ ret.blockPool.Put(buf.Dat)
}
+ return ret
}
func (bf *bufferedFile[A]) Name() string { return bf.inner.Name() }
@@ -57,7 +69,7 @@ func (bf *bufferedFile[A]) maybeShortReadAt(dat []byte, off A) (n int, err error
blockOffset := off - offsetWithinBlock
cachedBlock, ok := bf.blockCache.Load(blockOffset)
if !ok {
- cachedBlock.Dat = make([]byte, bf.blockSize)
+ cachedBlock.Dat, _ = bf.blockPool.Get()
n, err := bf.inner.ReadAt(cachedBlock.Dat, blockOffset)
cachedBlock.Dat = cachedBlock.Dat[:n]
cachedBlock.Err = err