summaryrefslogtreecommitdiff
path: root/lib/diskio
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-01-25 10:49:42 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-12 16:16:53 -0700
commitf6d5cc3e1ea4a9bb67b86e561f23e609f00727ec (patch)
tree955ad723e7da1d29ebce880d2d8fe0afdad0be42 /lib/diskio
parentfd89ca3095fc93f503d0cff6e0c380b2b67502f4 (diff)
diskio: BufferedFile: Refactor to avoid closures and parallel reads
Diffstat (limited to 'lib/diskio')
-rw-r--r--lib/diskio/file_blockbuf.go37
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