-
Notifications
You must be signed in to change notification settings - Fork 0
/
databaseops.cpp
97 lines (75 loc) · 2.39 KB
/
databaseops.cpp
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
#include "keyvalue.h"
#include "database.h"
#include "exceptions.h"
#include "memorysegment.h"
#include "multisegment.h"
#include "segment.h"
ByteBuffer Database::get(const Slice& key) {
ByteBuffer buffer;
return get(key,buffer);
}
ByteBuffer& Database::get(const Slice& key,ByteBuffer& value) {
if(!_open) throw DatabaseClosed();
checkKey(key);
return getState()->multi->get(key,value);
}
void Database::maybeMerge() {
if(options.disableAutoMerge) return;
auto state = getState();
if(state->segments.size()> 2*options.maxSegments) {
merger.wakeup();
}
}
void Database::maybeSwapMemory() {
auto state = getState();
if(state->memory->size() > options.maxMemoryBytes) {
auto segments = copyAndAppend(state->segments,state->memory);
auto memory = MemorySegment::newMemorySegment(path,nextSegmentID(),options);
auto multi = MultiSegment::newMultiSegment(copyAndAppend(segments,memory));
setState(DatabaseState(segments,memory,multi));
}
}
void Database::put(const Slice& key,const Slice& value) {
DB_LOCK();
if(!_open) throw DatabaseClosed();
checkKey(key);
maybeSwapMemory();
getState()->memory->put(key,value);
DB_UNLOCK();
maybeMerge();
}
ByteBuffer Database::remove(const Slice& key) {
DB_LOCK();
if(!_open) throw DatabaseClosed();
checkKey(key);
auto value = get(key);
if(value.empty()) return value;
maybeSwapMemory();
getState()->memory->remove(key);
DB_UNLOCK();
maybeMerge();
return value;
}
void Database::write(const WriteBatch& batch) {
{
DB_LOCK();
if(!_open) throw DatabaseClosed();
maybeSwapMemory();
getState()->memory.memory()->write(batch);
}
maybeMerge();
}
LookupRef Database::lookup(const Slice& lower,const Slice& upper) {
auto snapshot = Database::snapshot();
return snapshot->lookup(lower,upper);
}
SnapshotRef Database::snapshot() {
DB_LOCK();
if(!_open) throw DatabaseClosed();
auto state = getState();
auto segments = copyAndAppend(state->segments,state->memory);
auto memory = MemorySegment::newMemorySegment(path,nextSegmentID(),options);
auto multi = MultiSegment::newMultiSegment(copyAndAppend(segments,memory));
setState(DatabaseState(segments,memory,multi));
return SnapshotRef(new Snapshot(DatabaseRef(weakRef),MultiSegment::newMultiSegment(segments)));
}