-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitcask_helper.go
More file actions
120 lines (99 loc) · 2.81 KB
/
bitcask_helper.go
File metadata and controls
120 lines (99 loc) · 2.81 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package bitcask
import (
"os"
"path"
"time"
"github.com/Eslam-Nawara/bitcask/internal/datastore"
"github.com/Eslam-Nawara/bitcask/internal/keydir"
"github.com/Eslam-Nawara/bitcask/internal/recfmt"
)
func parseUsrOpts(opts []ConfigOpt) options {
usrOpts := options{
syncOption: SyncOnDemand,
accessPermission: ReadOnly,
}
for _, opt := range opts {
switch opt {
case SyncOnPut:
usrOpts.syncOption = SyncOnPut
case ReadWrite:
usrOpts.accessPermission = ReadWrite
}
}
return usrOpts
}
func (bitcask *Bitcask) setPermessions(dataStorePath string) (keydir.KeyDirPrivacy, datastore.LockMode) {
var privacy keydir.KeyDirPrivacy
var lockMode datastore.LockMode
if bitcask.usrOpts.accessPermission == ReadWrite {
privacy = keydir.PrivateKeyDir
lockMode = datastore.ExclusiveLock
fileFlags := os.O_CREATE | os.O_RDWR
if bitcask.usrOpts.syncOption == SyncOnPut {
fileFlags |= os.O_SYNC
}
bitcask.fileFlags = fileFlags
bitcask.activeFile = datastore.NewAppendFile(dataStorePath, bitcask.fileFlags, datastore.Active)
} else {
privacy = keydir.SharedKeyDir
lockMode = datastore.SharedLock
}
return privacy, lockMode
}
func (bitcask *Bitcask) listOldFiles() ([]string, error) {
oldFiles := make([]string, 0)
dataStore, err := os.Open(bitcask.dataStore.Path())
if err != nil {
return nil, err
}
defer dataStore.Close()
bitcask.accessMu.Lock()
files, err := dataStore.Readdir(0)
bitcask.accessMu.Unlock()
if err != nil {
return nil, err
}
for _, file := range files {
fileName := file.Name()
if fileName[0] != '.' && fileName != bitcask.activeFile.Name() && fileName != "keydir" {
oldFiles = append(oldFiles, fileName)
}
}
return oldFiles, nil
}
// mergeWrite performs a writing to the created merge file.
// returns the new record about the written data
// returns error if the data is deleted and will not be written again or on any system failures.
func (bitcask *Bitcask) mergeWrite(mergeFile *datastore.AppendFile, key string) (recfmt.KeyDirRec, error) {
rec := bitcask.keyDir[key]
value, err := bitcask.dataStore.ReadValueFromFile(rec.FileId, key, rec.ValuePos, rec.ValueSize)
if err != nil {
return recfmt.KeyDirRec{}, err
}
tStamp := time.Now().UnixMicro()
n, err := mergeFile.WriteData(key, value, tStamp)
if err != nil {
return recfmt.KeyDirRec{}, err
}
newRec := recfmt.KeyDirRec{
FileId: mergeFile.Name(),
ValuePos: uint32(n),
ValueSize: uint32(len(value)),
TStamp: tStamp,
}
err = mergeFile.WriteHint(key, newRec)
if err != nil {
return recfmt.KeyDirRec{}, err
}
return newRec, nil
}
// deleteOldFiles deletes all files passed to it.
func (bitcask *Bitcask) deleteOldFiles(files []string) error {
for _, file := range files {
err := os.Remove(path.Join(bitcask.dataStore.Path(), file))
if err != nil {
return err
}
}
return nil
}