Commit 83a89fc7 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Change BufferPool to an interface.

parent ed9d2c4e
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
// Typically, each call happens in its own goroutine, so take care to // Typically, each call happens in its own goroutine, so take care to
// make the file system thread-safe. // make the file system thread-safe.
// //
// Include DefaultFileSystem to provide default null implementation of // Include DefaultFileSystem to provide a default null implementation of
// required methods. // required methods.
type FileSystem interface { type FileSystem interface {
// Attributes // Attributes
...@@ -69,7 +69,7 @@ type FileSystem interface { ...@@ -69,7 +69,7 @@ type FileSystem interface {
// //
// TODO - should File be thread safe? // TODO - should File be thread safe?
type File interface { type File interface {
Read(*ReadIn, *BufferPool) ([]byte, Status) Read(*ReadIn, BufferPool) ([]byte, Status)
Write(*WriteIn, []byte) (written uint32, code Status) Write(*WriteIn, []byte) (written uint32, code Status)
Truncate(size uint64) Status Truncate(size uint64) Status
...@@ -137,7 +137,7 @@ type RawFileSystem interface { ...@@ -137,7 +137,7 @@ type RawFileSystem interface {
// File handling. // File handling.
Create(header *InHeader, input *CreateIn, name string) (flags uint32, handle uint64, out *EntryOut, code Status) Create(header *InHeader, input *CreateIn, name string) (flags uint32, handle uint64, out *EntryOut, code Status)
Open(header *InHeader, input *OpenIn) (flags uint32, handle uint64, status Status) Open(header *InHeader, input *OpenIn) (flags uint32, handle uint64, status Status)
Read(*ReadIn, *BufferPool) ([]byte, Status) Read(*ReadIn, BufferPool) ([]byte, Status)
Release(header *InHeader, input *ReleaseIn) Release(header *InHeader, input *ReleaseIn)
Write(*WriteIn, []byte) (written uint32, code Status) Write(*WriteIn, []byte) (written uint32, code Status)
......
...@@ -9,10 +9,30 @@ import ( ...@@ -9,10 +9,30 @@ import (
var _ = log.Println var _ = log.Println
type BufferPool interface {
AllocBuffer(size uint32) []byte
FreeBuffer(slice []byte)
}
type GcBufferPool struct {
}
// NewGcBufferPool is just a fallback to the standard allocation routines.
func NewGcBufferPool() *GcBufferPool {
return &GcBufferPool{}
}
func (me *GcBufferPool) AllocBuffer(size uint32) []byte {
return make([]byte, size)
}
func (me *GcBufferPool) FreeBuffer(slice []byte) {
}
// BufferPool implements a pool of buffers that returns slices with // BufferPool implements a pool of buffers that returns slices with
// capacity (2^e * PAGESIZE) for e=0,1,... which have possibly been // capacity (2^e * PAGESIZE) for e=0,1,... which have possibly been
// used, and may contain random contents. // used, and may contain random contents.
type BufferPool struct { type BufferPoolImpl struct {
lock sync.Mutex lock sync.Mutex
// For each exponent a list of slice pointers. // For each exponent a list of slice pointers.
...@@ -41,14 +61,14 @@ func IntToExponent(z int) uint { ...@@ -41,14 +61,14 @@ func IntToExponent(z int) uint {
return exp return exp
} }
func NewBufferPool() *BufferPool { func NewBufferPool() *BufferPoolImpl {
bp := new(BufferPool) bp := new(BufferPoolImpl)
bp.buffersByExponent = make([][][]byte, 0, 8) bp.buffersByExponent = make([][][]byte, 0, 8)
bp.outstandingBuffers = make(map[uintptr]uint) bp.outstandingBuffers = make(map[uintptr]uint)
return bp return bp
} }
func (me *BufferPool) String() string { func (me *BufferPoolImpl) String() string {
me.lock.Lock() me.lock.Lock()
defer me.lock.Unlock() defer me.lock.Unlock()
s := fmt.Sprintf("created: %v\noutstanding %v\n", s := fmt.Sprintf("created: %v\noutstanding %v\n",
...@@ -59,7 +79,7 @@ func (me *BufferPool) String() string { ...@@ -59,7 +79,7 @@ func (me *BufferPool) String() string {
return s return s
} }
func (me *BufferPool) getBuffer(exponent uint) []byte { func (me *BufferPoolImpl) getBuffer(exponent uint) []byte {
if len(me.buffersByExponent) <= int(exponent) { if len(me.buffersByExponent) <= int(exponent) {
return nil return nil
} }
...@@ -73,7 +93,7 @@ func (me *BufferPool) getBuffer(exponent uint) []byte { ...@@ -73,7 +93,7 @@ func (me *BufferPool) getBuffer(exponent uint) []byte {
return result return result
} }
func (me *BufferPool) addBuffer(slice []byte, exp uint) { func (me *BufferPoolImpl) addBuffer(slice []byte, exp uint) {
for len(me.buffersByExponent) <= int(exp) { for len(me.buffersByExponent) <= int(exp) {
me.buffersByExponent = append(me.buffersByExponent, make([][]byte, 0)) me.buffersByExponent = append(me.buffersByExponent, make([][]byte, 0))
} }
...@@ -82,7 +102,7 @@ func (me *BufferPool) addBuffer(slice []byte, exp uint) { ...@@ -82,7 +102,7 @@ func (me *BufferPool) addBuffer(slice []byte, exp uint) {
// AllocBuffer creates a buffer of at least the given size. After use, // AllocBuffer creates a buffer of at least the given size. After use,
// it should be deallocated with FreeBuffer(). // it should be deallocated with FreeBuffer().
func (me *BufferPool) AllocBuffer(size uint32) []byte { func (me *BufferPoolImpl) AllocBuffer(size uint32) []byte {
sz := int(size) sz := int(size)
if sz < PAGESIZE { if sz < PAGESIZE {
sz = PAGESIZE sz = PAGESIZE
...@@ -119,7 +139,7 @@ func (me *BufferPool) AllocBuffer(size uint32) []byte { ...@@ -119,7 +139,7 @@ func (me *BufferPool) AllocBuffer(size uint32) []byte {
// FreeBuffer takes back a buffer if it was allocated through // FreeBuffer takes back a buffer if it was allocated through
// AllocBuffer. It is not an error to call FreeBuffer() on a slice // AllocBuffer. It is not an error to call FreeBuffer() on a slice
// obtained elsewhere. // obtained elsewhere.
func (me *BufferPool) FreeBuffer(slice []byte) { func (me *BufferPoolImpl) FreeBuffer(slice []byte) {
if slice == nil { if slice == nil {
return return
} }
......
...@@ -100,7 +100,7 @@ func (me *DefaultRawFileSystem) OpenDir(header *InHeader, input *OpenIn) (flags ...@@ -100,7 +100,7 @@ func (me *DefaultRawFileSystem) OpenDir(header *InHeader, input *OpenIn) (flags
return 0, 0, ENOSYS return 0, 0, ENOSYS
} }
func (me *DefaultRawFileSystem) Read(*ReadIn, *BufferPool) ([]byte, Status) { func (me *DefaultRawFileSystem) Read(*ReadIn, BufferPool) ([]byte, Status) {
return nil, ENOSYS return nil, ENOSYS
} }
...@@ -137,7 +137,7 @@ func (me *DefaultRawFileSystem) Ioctl(header *InHeader, input *IoctlIn) (output ...@@ -137,7 +137,7 @@ func (me *DefaultRawFileSystem) Ioctl(header *InHeader, input *IoctlIn) (output
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// DefaultFile // DefaultFile
func (me *DefaultFile) Read(*ReadIn, *BufferPool) ([]byte, Status) { func (me *DefaultFile) Read(*ReadIn, BufferPool) ([]byte, Status) {
return []byte(""), ENOSYS return []byte(""), ENOSYS
} }
......
...@@ -18,7 +18,7 @@ func NewReadOnlyFile(data []byte) *ReadOnlyFile { ...@@ -18,7 +18,7 @@ func NewReadOnlyFile(data []byte) *ReadOnlyFile {
return f return f
} }
func (me *ReadOnlyFile) Read(input *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *ReadOnlyFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
end := int(input.Offset) + int(input.Size) end := int(input.Offset) + int(input.Size)
if end > len(me.data) { if end > len(me.data) {
end = len(me.data) end = len(me.data)
...@@ -38,7 +38,7 @@ func NewDevNullFile() *DevNullFile { ...@@ -38,7 +38,7 @@ func NewDevNullFile() *DevNullFile {
return new(DevNullFile) return new(DevNullFile)
} }
func (me *DevNullFile) Read(input *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *DevNullFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
return []byte{}, OK return []byte{}, OK
} }
...@@ -63,7 +63,7 @@ type LoopbackFile struct { ...@@ -63,7 +63,7 @@ type LoopbackFile struct {
DefaultFile DefaultFile
} }
func (me *LoopbackFile) Read(input *ReadIn, buffers *BufferPool) ([]byte, Status) { func (me *LoopbackFile) Read(input *ReadIn, buffers BufferPool) ([]byte, Status) {
slice := buffers.AllocBuffer(input.Size) slice := buffers.AllocBuffer(input.Size)
n, err := me.file.ReadAt(slice, int64(input.Offset)) n, err := me.file.ReadAt(slice, int64(input.Offset))
......
...@@ -17,7 +17,7 @@ type MutableDataFile struct { ...@@ -17,7 +17,7 @@ type MutableDataFile struct {
GetAttrCalled bool GetAttrCalled bool
} }
func (me *MutableDataFile) Read(r *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *MutableDataFile) Read(r *ReadIn, bp BufferPool) ([]byte, Status) {
return me.data[r.Offset : r.Offset+uint64(r.Size)], OK return me.data[r.Offset : r.Offset+uint64(r.Size)], OK
} }
......
...@@ -29,7 +29,7 @@ type MountState struct { ...@@ -29,7 +29,7 @@ type MountState struct {
Debug bool Debug bool
// For efficient reads and writes. // For efficient reads and writes.
buffers *BufferPool buffers *BufferPoolImpl
*LatencyMap *LatencyMap
......
...@@ -274,7 +274,7 @@ func (me *LockingRawFileSystem) ReleaseDir(header *InHeader, h *ReleaseIn) { ...@@ -274,7 +274,7 @@ func (me *LockingRawFileSystem) ReleaseDir(header *InHeader, h *ReleaseIn) {
me.RawFileSystem.ReleaseDir(header, h) me.RawFileSystem.ReleaseDir(header, h)
} }
func (me *LockingRawFileSystem) Read(input *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *LockingRawFileSystem) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
defer me.locked()() defer me.locked()()
return me.RawFileSystem.Read(input, bp) return me.RawFileSystem.Read(input, bp)
} }
......
...@@ -466,7 +466,7 @@ func (me *FileSystemConnector) Write(input *WriteIn, data []byte) (written uint3 ...@@ -466,7 +466,7 @@ func (me *FileSystemConnector) Write(input *WriteIn, data []byte) (written uint3
return f.Write(input, data) return f.Write(input, data)
} }
func (me *FileSystemConnector) Read(input *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *FileSystemConnector) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
f, _, n := me.getFile(input.Fh) f, _, n := me.getFile(input.Fh)
if me.Debug { if me.Debug {
me.fileDebug(input.Fh, n) me.fileDebug(input.Fh, n)
......
...@@ -141,7 +141,7 @@ func (me *TimingRawFileSystem) Release(header *InHeader, input *ReleaseIn) { ...@@ -141,7 +141,7 @@ func (me *TimingRawFileSystem) Release(header *InHeader, input *ReleaseIn) {
me.RawFileSystem.Release(header, input) me.RawFileSystem.Release(header, input)
} }
func (me *TimingRawFileSystem) Read(input *ReadIn, bp *BufferPool) ([]byte, Status) { func (me *TimingRawFileSystem) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
defer me.startTimer("Read")() defer me.startTimer("Read")()
return me.RawFileSystem.Read(input, bp) return me.RawFileSystem.Read(input, bp)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment