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