-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatalog.go
68 lines (59 loc) · 1.51 KB
/
datalog.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
package simpledb
import (
"math"
)
const maxSegments = math.MaxInt16
type datalog struct {
curSeg *segment
segments [maxSegments]*segment
}
func (dl *datalog) readKeyValue(sl *slot) ([]byte, []byte, error) {
seg := dl.segments[sl.segmentID]
off := sl.offset
keyStart := off+2 // 2 is the length of keySize
key, err := seg.Read(int64(keyStart), int64(sl.keySize))
if err != nil {
return nil, nil, err
}
valueStart := keyStart+uint32(sl.keySize)+4 // 4 is the length of valueSize
value, err := seg.Read(int64(valueStart), int64(sl.valueSize))
if err != nil {
return nil, nil, err
}
return key, value, nil
}
// If the current segment is full, create a new segment and set it as the current segment
func (dl * datalog) swapSegment() error {
curSegId := dl.curSeg.id
newSegId := curSegId + 1
newMmapFile, err := OpenMmapFile(segmentName(newSegId), 1)
if err != nil {
return err
}
dl.segments[newSegId] = &segment{
MmapFile: newMmapFile,
id: newSegId,
}
dl.curSeg = dl.segments[newSegId]
return nil
}
// @return: segmentID, offset
func (dl *datalog) writeRecord(data []byte) (uint16, int64, error) {
curSize := int(dl.curSeg.FileSize())
if curSize + len(data) > maxSegmentSize {
dl.curSeg.full = true
}
if dl.curSeg.full {
err := dl.swapSegment()
if err!=nil {
return 0, -1, err
}
}
newFileSize := dl.curSeg.FileSize() + int64(len(data))
err := dl.curSeg.MmapFile.Grow(newFileSize)
if err != nil {
return 0, -1, err
}
dl.curSeg.Append(data)
return dl.curSeg.id, int64(curSize), nil
}