diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-25 10:49:42 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 16:16:53 -0700 |
commit | f6d5cc3e1ea4a9bb67b86e561f23e609f00727ec (patch) | |
tree | 955ad723e7da1d29ebce880d2d8fe0afdad0be42 | |
parent | fd89ca3095fc93f503d0cff6e0c380b2b67502f4 (diff) |
diskio: BufferedFile: Refactor to avoid closures and parallel reads
-rw-r--r-- | lib/diskio/file_blockbuf.go | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/lib/diskio/file_blockbuf.go b/lib/diskio/file_blockbuf.go index 3db3105..b7db849 100644 --- a/lib/diskio/file_blockbuf.go +++ b/lib/diskio/file_blockbuf.go @@ -34,18 +34,30 @@ func NewBufferedFile[A ~int64](file File[A], blockSize A, cacheSize int) *buffer 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) } + ret.blockPool.New = ret.malloc + ret.blockCache.OnRemove = ret.free + ret.blockCache.New = ret.readBlock return ret } +func (bf *bufferedFile[A]) malloc() []byte { + return make([]byte, bf.blockSize) +} + +func (bf *bufferedFile[A]) free(_ A, buf bufferedBlock) { + bf.blockPool.Put(buf.Dat) +} + +func (bf *bufferedFile[A]) readBlock(blockOffset A) bufferedBlock { + dat, _ := bf.blockPool.Get() + n, err := bf.inner.ReadAt(dat, blockOffset) + return bufferedBlock{ + Dat: dat[:n], + Err: err, + } +} + func (bf *bufferedFile[A]) Name() string { return bf.inner.Name() } func (bf *bufferedFile[A]) Size() A { return bf.inner.Size() } func (bf *bufferedFile[A]) Close() error { return bf.inner.Close() } @@ -67,14 +79,7 @@ func (bf *bufferedFile[A]) maybeShortReadAt(dat []byte, off A) (n int, err error defer bf.mu.RUnlock() offsetWithinBlock := off % bf.blockSize blockOffset := off - offsetWithinBlock - cachedBlock, ok := bf.blockCache.Load(blockOffset) - if !ok { - cachedBlock.Dat, _ = bf.blockPool.Get() - n, err := bf.inner.ReadAt(cachedBlock.Dat, blockOffset) - cachedBlock.Dat = cachedBlock.Dat[:n] - cachedBlock.Err = err - bf.blockCache.Store(blockOffset, cachedBlock) - } + cachedBlock, _ := bf.blockCache.Load(blockOffset) n = copy(dat, cachedBlock.Dat[offsetWithinBlock:]) if n < len(dat) { return n, cachedBlock.Err |