1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef _MDB_
7 # include "mdb.h"
8 #endif
9
10 #ifndef _MORK_
11 # include "mork.h"
12 #endif
13
14 #ifndef _MORKNODE_
15 # include "morkNode.h"
16 #endif
17
18 #ifndef _MORKENV_
19 # include "morkEnv.h"
20 #endif
21
22 #ifndef _MORKMAP_
23 # include "morkMap.h"
24 #endif
25
26 #ifndef _MORKATOMMAP_
27 # include "morkAtomMap.h"
28 #endif
29
30 #ifndef _MORKATOM_
31 # include "morkAtom.h"
32 #endif
33
34 #ifndef _MORKINTMAP_
35 # include "morkIntMap.h"
36 #endif
37
38 #ifndef _MORKROW_
39 # include "morkRow.h"
40 #endif
41
42 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
43
44 // ````` ````` ````` ````` `````
45 // { ===== begin morkNode interface =====
46
CloseMorkNode(morkEnv * ev)47 /*public virtual*/ void morkAtomAidMap::CloseMorkNode(
48 morkEnv* ev) // CloseAtomAidMap() only if open
49 {
50 if (this->IsOpenNode()) {
51 this->MarkClosing();
52 this->CloseAtomAidMap(ev);
53 this->MarkShut();
54 }
55 }
56
57 /*public virtual*/
~morkAtomAidMap()58 morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier
59 {
60 MORK_ASSERT(this->IsShutNode());
61 }
62
63 /*public non-poly*/
morkAtomAidMap(morkEnv * ev,const morkUsage & inUsage,nsIMdbHeap * ioHeap,nsIMdbHeap * ioSlotHeap)64 morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
65 nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
66 #ifdef MORK_ENABLE_PROBE_MAPS
67 : morkProbeMap(ev, inUsage, ioHeap,
68 /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
69 ioSlotHeap, morkAtomAidMap_kStartSlotCount,
70 /*inZeroIsClearKey*/ morkBool_kTrue)
71 #else /*MORK_ENABLE_PROBE_MAPS*/
72 : morkMap(ev, inUsage, ioHeap,
73 /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
74 morkAtomAidMap_kStartSlotCount, ioSlotHeap,
75 /*inHoldChanges*/ morkBool_kFalse)
76 #endif /*MORK_ENABLE_PROBE_MAPS*/
77 {
78 if (ev->Good()) mNode_Derived = morkDerived_kAtomAidMap;
79 }
80
CloseAtomAidMap(morkEnv * ev)81 /*public non-poly*/ void morkAtomAidMap::CloseAtomAidMap(
82 morkEnv* ev) // called by CloseMorkNode();
83 {
84 if (this->IsNode()) {
85 #ifdef MORK_ENABLE_PROBE_MAPS
86 this->CloseProbeMap(ev);
87 #else /*MORK_ENABLE_PROBE_MAPS*/
88 this->CloseMap(ev);
89 #endif /*MORK_ENABLE_PROBE_MAPS*/
90 this->MarkShut();
91 } else
92 this->NonNodeError(ev);
93 }
94
95 // } ===== end morkNode methods =====
96 // ````` ````` ````` ````` `````
97
98 #ifdef MORK_ENABLE_PROBE_MAPS
99
100 /*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b)
MapTest(morkEnv * ev,const void * inMapKey,const void * inAppKey) const101 morkAtomAidMap::MapTest(morkEnv* ev, const void* inMapKey,
102 const void* inAppKey) const {
103 MORK_USED_1(ev);
104 const morkBookAtom* key = *(const morkBookAtom**)inMapKey;
105 if (key) {
106 mork_bool hit = key->EqualAid(*(const morkBookAtom**)inAppKey);
107 return (hit) ? morkTest_kHit : morkTest_kMiss;
108 } else
109 return morkTest_kVoid;
110 }
111
112 /*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b)
MapHash(morkEnv * ev,const void * inAppKey) const113 morkAtomAidMap::MapHash(morkEnv* ev, const void* inAppKey) const {
114 const morkBookAtom* key = *(const morkBookAtom**)inAppKey;
115 if (key)
116 return key->HashAid();
117 else {
118 ev->NilPointerWarning();
119 return 0;
120 }
121 }
122
ProbeMapHashMapKey(morkEnv * ev,const void * inMapKey) const123 /*virtual*/ mork_u4 morkAtomAidMap::ProbeMapHashMapKey(
124 morkEnv* ev, const void* inMapKey) const {
125 const morkBookAtom* key = *(const morkBookAtom**)inMapKey;
126 if (key)
127 return key->HashAid();
128 else {
129 ev->NilPointerWarning();
130 return 0;
131 }
132 }
133 #else /*MORK_ENABLE_PROBE_MAPS*/
134 // { ===== begin morkMap poly interface =====
135 /*virtual*/ mork_bool //
Equal(morkEnv * ev,const void * inKeyA,const void * inKeyB) const136 morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
137 const void* inKeyB) const {
138 MORK_USED_1(ev);
139 return (*(const morkBookAtom**)inKeyA)
140 ->EqualAid(*(const morkBookAtom**)inKeyB);
141 }
142
143 /*virtual*/ mork_u4 //
Hash(morkEnv * ev,const void * inKey) const144 morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const {
145 MORK_USED_1(ev);
146 return (*(const morkBookAtom**)inKey)->HashAid();
147 }
148 // } ===== end morkMap poly interface =====
149 #endif /*MORK_ENABLE_PROBE_MAPS*/
150
AddAtom(morkEnv * ev,morkBookAtom * ioAtom)151 mork_bool morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom) {
152 if (ev->Good()) {
153 #ifdef MORK_ENABLE_PROBE_MAPS
154 this->MapAtPut(ev, &ioAtom, /*val*/ (void*)0,
155 /*key*/ (void*)0, /*val*/ (void*)0);
156 #else /*MORK_ENABLE_PROBE_MAPS*/
157 this->Put(ev, &ioAtom, /*val*/ (void*)0,
158 /*key*/ (void*)0, /*val*/ (void*)0, (mork_change**)0);
159 #endif /*MORK_ENABLE_PROBE_MAPS*/
160 }
161 return ev->Good();
162 }
163
CutAtom(morkEnv * ev,const morkBookAtom * inAtom)164 morkBookAtom* morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom) {
165 morkBookAtom* oldKey = 0;
166
167 #ifdef MORK_ENABLE_PROBE_MAPS
168 MORK_USED_1(inAtom);
169 morkProbeMap::ProbeMapCutError(ev);
170 #else /*MORK_ENABLE_PROBE_MAPS*/
171 this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*)0, (mork_change**)0);
172 #endif /*MORK_ENABLE_PROBE_MAPS*/
173
174 return oldKey;
175 }
176
GetAtom(morkEnv * ev,const morkBookAtom * inAtom)177 morkBookAtom* morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom) {
178 morkBookAtom* key = 0; // old val in the map
179
180 #ifdef MORK_ENABLE_PROBE_MAPS
181 this->MapAt(ev, &inAtom, &key, /*val*/ (void*)0);
182 #else /*MORK_ENABLE_PROBE_MAPS*/
183 this->Get(ev, &inAtom, &key, /*val*/ (void*)0, (mork_change**)0);
184 #endif /*MORK_ENABLE_PROBE_MAPS*/
185
186 return key;
187 }
188
GetAid(morkEnv * ev,mork_aid inAid)189 morkBookAtom* morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid) {
190 morkWeeBookAtom weeAtom(inAid);
191 morkBookAtom* key = &weeAtom; // we need a pointer
192 morkBookAtom* oldKey = 0; // old key in the map
193
194 #ifdef MORK_ENABLE_PROBE_MAPS
195 this->MapAt(ev, &key, &oldKey, /*val*/ (void*)0);
196 #else /*MORK_ENABLE_PROBE_MAPS*/
197 this->Get(ev, &key, &oldKey, /*val*/ (void*)0, (mork_change**)0);
198 #endif /*MORK_ENABLE_PROBE_MAPS*/
199
200 return oldKey;
201 }
202
203 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
204
205 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
206
207 // ````` ````` ````` ````` `````
208 // { ===== begin morkNode interface =====
209
CloseMorkNode(morkEnv * ev)210 /*public virtual*/ void morkAtomBodyMap::CloseMorkNode(
211 morkEnv* ev) // CloseAtomBodyMap() only if open
212 {
213 if (this->IsOpenNode()) {
214 this->MarkClosing();
215 this->CloseAtomBodyMap(ev);
216 this->MarkShut();
217 }
218 }
219
220 /*public virtual*/
~morkAtomBodyMap()221 morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed
222 // earlier
223 {
224 MORK_ASSERT(this->IsShutNode());
225 }
226
227 /*public non-poly*/
morkAtomBodyMap(morkEnv * ev,const morkUsage & inUsage,nsIMdbHeap * ioHeap,nsIMdbHeap * ioSlotHeap)228 morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
229 nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
230 #ifdef MORK_ENABLE_PROBE_MAPS
231 : morkProbeMap(ev, inUsage, ioHeap,
232 /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
233 ioSlotHeap, morkAtomBodyMap_kStartSlotCount,
234 /*inZeroIsClearKey*/ morkBool_kTrue)
235 #else /*MORK_ENABLE_PROBE_MAPS*/
236 : morkMap(ev, inUsage, ioHeap,
237 /*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
238 morkAtomBodyMap_kStartSlotCount, ioSlotHeap,
239 /*inHoldChanges*/ morkBool_kFalse)
240 #endif /*MORK_ENABLE_PROBE_MAPS*/
241 {
242 if (ev->Good()) mNode_Derived = morkDerived_kAtomBodyMap;
243 }
244
CloseAtomBodyMap(morkEnv * ev)245 /*public non-poly*/ void morkAtomBodyMap::CloseAtomBodyMap(
246 morkEnv* ev) // called by CloseMorkNode();
247 {
248 if (this->IsNode()) {
249 #ifdef MORK_ENABLE_PROBE_MAPS
250 this->CloseProbeMap(ev);
251 #else /*MORK_ENABLE_PROBE_MAPS*/
252 this->CloseMap(ev);
253 #endif /*MORK_ENABLE_PROBE_MAPS*/
254 this->MarkShut();
255 } else
256 this->NonNodeError(ev);
257 }
258
259 // } ===== end morkNode methods =====
260 // ````` ````` ````` ````` `````
261 #ifdef MORK_ENABLE_PROBE_MAPS
262
263 /*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b)
MapTest(morkEnv * ev,const void * inMapKey,const void * inAppKey) const264 morkAtomBodyMap::MapTest(morkEnv* ev, const void* inMapKey,
265 const void* inAppKey) const {
266 const morkBookAtom* key = *(const morkBookAtom**)inMapKey;
267 if (key) {
268 return (key->EqualFormAndBody(ev, *(const morkBookAtom**)inAppKey))
269 ? morkTest_kHit
270 : morkTest_kMiss;
271 } else
272 return morkTest_kVoid;
273 }
274
275 /*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b)
MapHash(morkEnv * ev,const void * inAppKey) const276 morkAtomBodyMap::MapHash(morkEnv* ev, const void* inAppKey) const {
277 const morkBookAtom* key = *(const morkBookAtom**)inAppKey;
278 if (key)
279 return key->HashFormAndBody(ev);
280 else
281 return 0;
282 }
283
ProbeMapHashMapKey(morkEnv * ev,const void * inMapKey) const284 /*virtual*/ mork_u4 morkAtomBodyMap::ProbeMapHashMapKey(
285 morkEnv* ev, const void* inMapKey) const {
286 const morkBookAtom* key = *(const morkBookAtom**)inMapKey;
287 if (key)
288 return key->HashFormAndBody(ev);
289 else
290 return 0;
291 }
292 #else /*MORK_ENABLE_PROBE_MAPS*/
293 // { ===== begin morkMap poly interface =====
294 /*virtual*/ mork_bool //
Equal(morkEnv * ev,const void * inKeyA,const void * inKeyB) const295 morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA,
296 const void* inKeyB) const {
297 return (*(const morkBookAtom**)inKeyA)
298 ->EqualFormAndBody(ev, *(const morkBookAtom**)inKeyB);
299 }
300
301 /*virtual*/ mork_u4 //
Hash(morkEnv * ev,const void * inKey) const302 morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const {
303 return (*(const morkBookAtom**)inKey)->HashFormAndBody(ev);
304 }
305 // } ===== end morkMap poly interface =====
306 #endif /*MORK_ENABLE_PROBE_MAPS*/
307
AddAtom(morkEnv * ev,morkBookAtom * ioAtom)308 mork_bool morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom) {
309 if (ev->Good()) {
310 #ifdef MORK_ENABLE_PROBE_MAPS
311 this->MapAtPut(ev, &ioAtom, /*val*/ (void*)0,
312 /*key*/ (void*)0, /*val*/ (void*)0);
313 #else /*MORK_ENABLE_PROBE_MAPS*/
314 this->Put(ev, &ioAtom, /*val*/ (void*)0,
315 /*key*/ (void*)0, /*val*/ (void*)0, (mork_change**)0);
316 #endif /*MORK_ENABLE_PROBE_MAPS*/
317 }
318 return ev->Good();
319 }
320
CutAtom(morkEnv * ev,const morkBookAtom * inAtom)321 morkBookAtom* morkAtomBodyMap::CutAtom(morkEnv* ev,
322 const morkBookAtom* inAtom) {
323 morkBookAtom* oldKey = 0;
324
325 #ifdef MORK_ENABLE_PROBE_MAPS
326 MORK_USED_1(inAtom);
327 morkProbeMap::ProbeMapCutError(ev);
328 #else /*MORK_ENABLE_PROBE_MAPS*/
329 this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*)0, (mork_change**)0);
330 #endif /*MORK_ENABLE_PROBE_MAPS*/
331
332 return oldKey;
333 }
334
GetAtom(morkEnv * ev,const morkBookAtom * inAtom)335 morkBookAtom* morkAtomBodyMap::GetAtom(morkEnv* ev,
336 const morkBookAtom* inAtom) {
337 morkBookAtom* key = 0; // old val in the map
338 #ifdef MORK_ENABLE_PROBE_MAPS
339 this->MapAt(ev, &inAtom, &key, /*val*/ (void*)0);
340 #else /*MORK_ENABLE_PROBE_MAPS*/
341 this->Get(ev, &inAtom, &key, /*val*/ (void*)0, (mork_change**)0);
342 #endif /*MORK_ENABLE_PROBE_MAPS*/
343
344 return key;
345 }
346
347 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
348
~morkAtomRowMap()349 morkAtomRowMap::~morkAtomRowMap() {}
350
351 // I changed to sizeof(mork_ip) from sizeof(mork_aid) to fix a crash on
352 // 64 bit machines. I am not sure it was the right way to fix the problem,
353 // but it does stop the crash. Perhaps we should be using the
354 // morkPointerMap instead?
morkAtomRowMap(morkEnv * ev,const morkUsage & inUsage,nsIMdbHeap * ioHeap,nsIMdbHeap * ioSlotHeap,mork_column inIndexColumn)355 morkAtomRowMap::morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
356 nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
357 mork_column inIndexColumn)
358 : morkIntMap(ev, inUsage, sizeof(mork_ip), ioHeap, ioSlotHeap,
359 /*inHoldChanges*/ morkBool_kFalse),
360 mAtomRowMap_IndexColumn(inIndexColumn) {
361 if (ev->Good()) mNode_Derived = morkDerived_kAtomRowMap;
362 }
363
AddRow(morkEnv * ev,morkRow * ioRow)364 void morkAtomRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
365 // add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
366 {
367 mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
368 if (aid) this->AddAid(ev, aid, ioRow);
369 }
370
CutRow(morkEnv * ev,morkRow * ioRow)371 void morkAtomRowMap::CutRow(morkEnv* ev, morkRow* ioRow)
372 // cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
373 {
374 mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
375 if (aid) this->CutAid(ev, aid);
376 }
377
378 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
379