-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjs_dbver.c
123 lines (88 loc) · 3 KB
/
js_dbver.c
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
121
122
123
#include "js.h"
#include "js_db.h"
#include "js_dbindex.h"
#include <stddef.h>
// insert a document or an updated version into a docStore
// returns prev document addr from the slot
JsStatus writeRawDoc(Handle *docHndl, value_t val, ObjId *docId) {
DbMap *map = MapAddr(docHndl);
uint32_t docSize, rawSize, baseOff;
DbAddr newAddr, prevAddr;
document_t *rawDoc;
JsDoc *jsDoc; // follows document
DbAddr *docSlot;
value_t s;
s.bits = vt_status;
docSize = calcSize(val, true);
docSlot = fetchIdSlot(map, *docId);
prevAddr = *docSlot;
DocIdXtra(docId)->txnAccess = TxnRaw;
rawSize = docSize + sizeof(JsDoc) + sizeof(struct Document);
// allocate space in docStore for the document
if ((newAddr.bits = allocDocStore(docHndl, rawSize, false)))
rawSize = db_rawSize(newAddr);
else
return (JsStatus)ERROR_outofmemory;
// set up the document header
rawDoc = getObj(map, newAddr);
memset(rawDoc, 0, sizeof(struct Document));
rawDoc->ourAddr.bits = newAddr.bits;
rawDoc->docId.bits = docId->bits;
rawDoc->docType = VerRaw;
jsDoc = (JsDoc *)(rawDoc + 1);
jsDoc->maxOffset = rawSize;
baseOff = sizeof(struct Document) + sizeof(JsDoc);
// marshal directly into the mmap file
marshalDoc(val, rawDoc->base, baseOff, docSize, jsDoc->value, true);
// install the document in the slot
// and return old addr
docSlot->bits = newAddr.bits;
return (JsStatus)prevAddr.bits;
}
// write/update mvcc doc
JsStatus writeMVCCDoc(Handle *docHndl, value_t val, ObjId *docId) {
DbMap *map = MapAddr(docHndl);
uint32_t docSize, baseOff;
MVCCResult result;
DbAddr *docSlot;
JsDoc *jsDoc;
value_t s;
Doc *doc; // follows Document
Ver *ver;
s.bits = vt_status;
docSize = calcSize(val, true);
docSlot = fetchIdSlot(map, *docId);
result = mvcc_installNewDocVer(docHndl, sizeof(JsDoc) + docSize, docId);
doc = result.object;
ver = (Ver *)(doc->doc->base + doc->newestVer);
jsDoc = (JsDoc *)(ver + 1);
baseOff = doc->newestVer - sizeof(Ver) - sizeof(JsDoc) - docSize;
// marshal directly into the mmap file
marshalDoc(val, doc->doc->base, baseOff, docSize, jsDoc->value, true);
return (JsStatus)DB_OK;
}
JsStatus writeDoc(Handle *docHndl, value_t val, ObjId *docId) {
struct Document *prevDoc;
DocStore *docStore;
JsStatus stat = (JsStatus)DB_OK;
DbMap *docMap;
docMap = MapAddr(docHndl);
docStore = (DocStore *)(docMap->arena + 1);
if(docId->bits == 0)
docId->bits = allocObjId(docMap, listFree(docHndl, 0), listWait(docHndl, 0));
switch (docStore->docType) {
case VerRaw:
DocIdXtra(docId)->txnAccess = TxnRaw;
prevDoc = writeRawDoc(docHndl, val, docId);
if (jsError(prevDoc))
stat = (JsStatus)prevDoc;
break;
case VerMvcc:
DocIdXtra(docId)->txnAccess = TxnWrt;
prevDoc = writeMVCCDoc(docHndl, val, docId);
if (jsError(prevDoc))
stat = (JsStatus)prevDoc;
break;
}
return stat;
}