-
Notifications
You must be signed in to change notification settings - Fork 9
/
store_memory.go
96 lines (80 loc) · 2.19 KB
/
store_memory.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// bagdb: Simple datastorage
// Copyright 2021 billy authors
// SPDX-License-Identifier: BSD-3-Clause
package billy
import (
"errors"
"io"
"os"
"sync"
)
// memoryStore implements store for in-memory ephemeral data persistence.
type memoryStore struct {
buffer []byte
lock sync.Mutex
}
// ReadAt implements io.ReaderAt of the store interface.
func (ms *memoryStore) ReadAt(p []byte, off int64) (int, error) {
ms.lock.Lock()
defer ms.lock.Unlock()
return ms.readAt(p, off)
}
// readAt is the actual implementation of Read/ReadAt.
func (ms *memoryStore) readAt(p []byte, off int64) (int, error) {
if off < 0 {
return 0, errors.New("memoryStore.ReadAt: negative offset")
}
if off >= int64(len(ms.buffer)) {
return 0, io.EOF
}
copy(p, ms.buffer[off:])
read := len(p)
fail := error(nil)
if off += int64(read); off > int64(len(ms.buffer)) {
read -= int(off - int64(len(ms.buffer)))
fail = io.EOF
}
return read, fail
}
// WriteAt implements io.WriterAt of the store interface.
func (ms *memoryStore) WriteAt(p []byte, off int64) (int, error) {
ms.lock.Lock()
defer ms.lock.Unlock()
return ms.writeAt(p, off)
}
// writeAt is the actual implementation of Write/WriteAt.
func (ms *memoryStore) writeAt(p []byte, off int64) (int, error) {
if off < 0 {
return 0, errors.New("memoryStore.WriteAt: negative offset")
}
if off+int64(len(p)) > int64(len(ms.buffer)) {
ms.buffer = append(ms.buffer, make([]byte, off+int64(len(p))-int64(len(ms.buffer)))...)
}
copy(ms.buffer[off:], p)
return len(p), nil
}
// Close implements io.Closer of the store interface.
func (ms *memoryStore) Close() error {
return nil
}
// Stat implements the store interface.
func (ms *memoryStore) Stat() (os.FileInfo, error) {
ms.lock.Lock()
defer ms.lock.Unlock()
return &fileinfoMock{size: int64(len(ms.buffer))}, nil
}
// Truncate implements the store interface.
func (ms *memoryStore) Truncate(size int64) error {
ms.lock.Lock()
defer ms.lock.Unlock()
if int64(len(ms.buffer)) >= size {
ms.buffer = ms.buffer[:size]
} else {
ms.buffer = append(ms.buffer, make([]byte, size-int64(len(ms.buffer)))...)
}
return nil
}
// Sync implements the store interface.
func (ms *memoryStore) Sync() error {
return nil
}