/
lifetime.go
95 lines (79 loc) · 1.69 KB
/
lifetime.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
package badger
import (
"encoding/binary"
"os"
"sync"
"github.com/outcaste-io/badger/v4/y"
"github.com/outcaste-io/ristretto/z"
)
type LifetimeStats struct {
sync.RWMutex
mf *z.MmapFile
}
var (
maxSz int = 1 << 20
idxVersion int = 0
idxOpen int = 1
idxClose int = 2
idxNumWrites int = 3
idxReservedBelow int = 128
)
func InitLifetimeStats(path string) *LifetimeStats {
mf, err := z.OpenMmapFile(path, os.O_RDWR|os.O_CREATE, maxSz)
if err == z.NewFile {
for i := range mf.Data {
mf.Data[i] = 0x0
}
y.Check(mf.Sync())
err = nil
}
y.Check(err)
lf := &LifetimeStats{mf: mf}
lf.updateAt(idxOpen, 1)
return lf
}
func getOffset(idx int) int {
off := idx * 8
y.AssertTrue(off < maxSz)
return off
}
func (lf *LifetimeStats) readAt(idx int) uint64 {
offset := getOffset(idx)
return binary.BigEndian.Uint64(lf.mf.Data[offset : offset+8])
}
func (lf *LifetimeStats) updateAt(idx int, delta uint64) {
val := lf.readAt(idx)
val += delta
off := getOffset(idx)
binary.BigEndian.PutUint64(lf.mf.Data[off:off+8], val)
}
func (lf *LifetimeStats) ReadAt(idx int) uint64 {
lf.RLock()
val := lf.readAt(idx)
lf.RUnlock()
return val
}
func (lf *LifetimeStats) UpdateAt(idx int, delta uint64) {
lf.Lock()
defer lf.Unlock()
y.AssertTrue(idx > idxReservedBelow)
lf.updateAt(idx, delta)
lf.updateAt(idxNumWrites, 1)
}
func (lf *LifetimeStats) Close() error {
lf.Lock()
defer lf.Unlock()
lf.updateAt(idxClose, 1)
return lf.mf.Close(-1)
}
func (lf *LifetimeStats) Stats() map[int]uint64 {
res := make(map[int]uint64)
lf.RLock()
for i := 0; i < (1<<20)/8; i++ {
if val := lf.readAt(i); val > 0 {
res[i] = val
}
}
lf.RUnlock()
return res
}