-
Notifications
You must be signed in to change notification settings - Fork 2
/
inmem.go
51 lines (43 loc) · 1.38 KB
/
inmem.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package io
import "errors"
var _ BlockFile = (*InMem)(nil)
// InMem implements an ephemeral BlockFile using in-memory byte slice.
// This implementation of BlockFile is meant for testing only.
type InMem struct {
blockSz int
readOnly bool
closed bool
data []byte
}
// Slice returns a slice of the memory mapped region starting at the block
// with the given id. Incorrect handling of the returned slice can cause
// segfaults or unexpected behavior. Any Alloc() calls will invalidate the
// returned slice.
func (mem *InMem) Slice(id int) ([]byte, error) {
offset := id * mem.blockSz
if id < 0 || offset >= len(mem.data) {
return nil, errors.New("non-existent block")
}
return mem.data[offset:], nil
}
// Alloc allocates n new sequential blocks and returns the id of the first.
func (mem *InMem) Alloc(n int) (int, []byte, error) {
size := mem.blockSz * n
id := len(mem.data) / mem.blockSz
mem.data = append(mem.data, make([]byte, size)...)
sl, err := mem.Slice(id)
return id, sl, err
}
// Info returns information about the block file state/configuration.
func (mem *InMem) Info() (name string, count, blockSz int, readOnly bool) {
return ":memory:", len(mem.data) / mem.blockSz, mem.blockSz, mem.readOnly
}
// Close flushes any pending writes and closes the file.
func (mem *InMem) Close() error {
if mem.closed {
return nil
}
mem.data = nil
mem.closed = true
return nil
}