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 _MORKATOMMAP_ 7 #define _MORKATOMMAP_ 1 8 9 #ifndef _MORK_ 10 # include "mork.h" 11 #endif 12 13 #ifndef _MORKNODE_ 14 # include "morkNode.h" 15 #endif 16 17 #ifndef _MORKMAP_ 18 # include "morkMap.h" 19 #endif 20 21 #ifndef _MORKPROBEMAP_ 22 # include "morkProbeMap.h" 23 #endif 24 25 #ifndef _MORKINTMAP_ 26 # include "morkIntMap.h" 27 #endif 28 29 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 30 31 #define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */ 32 33 #define morkAtomAidMap_kStartSlotCount 23 34 35 /*| morkAtomAidMap: keys of morkBookAtom organized by atom ID 36 |*/ 37 #ifdef MORK_ENABLE_PROBE_MAPS 38 class morkAtomAidMap : public morkProbeMap { // for mapping tokens to maps 39 #else /*MORK_ENABLE_PROBE_MAPS*/ 40 class morkAtomAidMap : public morkMap { // for mapping tokens to maps 41 #endif /*MORK_ENABLE_PROBE_MAPS*/ 42 43 // { ===== begin morkNode interface ===== 44 public: // morkNode virtual methods 45 virtual void CloseMorkNode( 46 morkEnv* ev) override; // CloseAtomAidMap() only if open 47 virtual ~morkAtomAidMap(); // assert that CloseAtomAidMap() executed earlier 48 49 public: // morkMap construction & destruction 50 morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 51 nsIMdbHeap* ioSlotHeap); 52 void CloseAtomAidMap(morkEnv* ev); // called by CloseMorkNode(); 53 54 public: // dynamic type identification IsAtomAidMap()55 mork_bool IsAtomAidMap() const { 56 return IsNode() && mNode_Derived == morkDerived_kAtomAidMap; 57 } 58 // } ===== end morkNode methods ===== 59 60 public: 61 #ifdef MORK_ENABLE_PROBE_MAPS 62 // { ===== begin morkProbeMap methods ===== 63 virtual mork_test // hit(a,b) implies hash(a) == hash(b) 64 MapTest(morkEnv* ev, const void* inMapKey, 65 const void* inAppKey) const override; 66 67 virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) 68 MapHash(morkEnv* ev, const void* inAppKey) const override; 69 70 virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, 71 const void* inMapKey) const override; 72 73 // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); 74 75 // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' into all keys 76 // inside map 77 // void* ioMapKey, mork_count inKeyCount); // array of keys inside map 78 79 // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map 80 // const void* inAppKey, const void* inAppVal, // (key,val) outside map 81 // void* outMapKey, void* outMapVal); // (key,val) inside map 82 83 // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the 84 // map 85 // const void* inMapKey, const void* inMapVal, // (key,val) inside map 86 // void* outAppKey, void* outAppVal) const; // (key,val) outside map 87 // } ===== end morkProbeMap methods ===== 88 #else /*MORK_ENABLE_PROBE_MAPS*/ 89 // { ===== begin morkMap poly interface ===== 90 virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) 91 Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const override; 92 // implemented using morkBookAtom::HashAid() 93 94 virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) 95 Hash(morkEnv* ev, const void* inKey) const override; 96 // implemented using morkBookAtom::EqualAid() 97 // } ===== end morkMap poly interface ===== 98 #endif /*MORK_ENABLE_PROBE_MAPS*/ 99 100 public: // other map methods 101 mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom); 102 // AddAtom() returns ev->Good() 103 104 morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom); 105 // CutAtom() returns the atom removed equal to inAtom, if there was one 106 107 morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom); 108 // GetAtom() returns the atom equal to inAtom, or else nil 109 110 morkBookAtom* GetAid(morkEnv* ev, mork_aid inAid); 111 // GetAid() returns the atom equal to inAid, or else nil 112 113 // note the atoms are owned elsewhere, usually by morkAtomSpace 114 115 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakAtomAidMap(morkAtomAidMap * me,morkEnv * ev,morkAtomAidMap ** ioSlot)116 static void SlotWeakAtomAidMap(morkAtomAidMap* me, morkEnv* ev, 117 morkAtomAidMap** ioSlot) { 118 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 119 } 120 SlotStrongAtomAidMap(morkAtomAidMap * me,morkEnv * ev,morkAtomAidMap ** ioSlot)121 static void SlotStrongAtomAidMap(morkAtomAidMap* me, morkEnv* ev, 122 morkAtomAidMap** ioSlot) { 123 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 124 } 125 }; 126 127 #ifdef MORK_ENABLE_PROBE_MAPS 128 class morkAtomAidMapIter : public morkProbeMapIter { // typesafe wrapper class 129 #else /*MORK_ENABLE_PROBE_MAPS*/ 130 class morkAtomAidMapIter : public morkMapIter { // typesafe wrapper class 131 #endif /*MORK_ENABLE_PROBE_MAPS*/ 132 133 public: 134 #ifdef MORK_ENABLE_PROBE_MAPS morkAtomAidMapIter(morkEnv * ev,morkAtomAidMap * ioMap)135 morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) 136 : morkProbeMapIter(ev, ioMap) {} 137 morkAtomAidMapIter()138 morkAtomAidMapIter() : morkProbeMapIter() {} 139 #else /*MORK_ENABLE_PROBE_MAPS*/ 140 morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) 141 : morkMapIter(ev, ioMap) {} 142 143 morkAtomAidMapIter() : morkMapIter() {} 144 #endif /*MORK_ENABLE_PROBE_MAPS*/ 145 InitAtomAidMapIter(morkEnv * ev,morkAtomAidMap * ioMap)146 void InitAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap) { 147 this->InitMapIter(ev, ioMap); 148 } 149 FirstAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)150 mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 151 return this->First(ev, outAtomPtr, /*val*/ (void*)0); 152 } 153 NextAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)154 mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 155 return this->Next(ev, outAtomPtr, /*val*/ (void*)0); 156 } 157 HereAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)158 mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 159 return this->Here(ev, outAtomPtr, /*val*/ (void*)0); 160 } 161 CutHereAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)162 mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 163 return this->CutHere(ev, outAtomPtr, /*val*/ (void*)0); 164 } 165 }; 166 167 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 168 169 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 170 171 #define morkDerived_kAtomBodyMap /*i*/ 0x6142 /* ascii 'aB' */ 172 173 #define morkAtomBodyMap_kStartSlotCount 23 174 175 /*| morkAtomBodyMap: keys of morkBookAtom organized by body bytes 176 |*/ 177 #ifdef MORK_ENABLE_PROBE_MAPS 178 class morkAtomBodyMap : public morkProbeMap { // for mapping tokens to maps 179 #else /*MORK_ENABLE_PROBE_MAPS*/ 180 class morkAtomBodyMap : public morkMap { // for mapping tokens to maps 181 #endif /*MORK_ENABLE_PROBE_MAPS*/ 182 183 // { ===== begin morkNode interface ===== 184 public: // morkNode virtual methods 185 virtual void CloseMorkNode( 186 morkEnv* ev) override; // CloseAtomBodyMap() only if open 187 virtual ~morkAtomBodyMap(); // assert CloseAtomBodyMap() executed earlier 188 189 public: // morkMap construction & destruction 190 morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 191 nsIMdbHeap* ioSlotHeap); 192 void CloseAtomBodyMap(morkEnv* ev); // called by CloseMorkNode(); 193 194 public: // dynamic type identification IsAtomBodyMap()195 mork_bool IsAtomBodyMap() const { 196 return IsNode() && mNode_Derived == morkDerived_kAtomBodyMap; 197 } 198 // } ===== end morkNode methods ===== 199 200 public: 201 #ifdef MORK_ENABLE_PROBE_MAPS 202 // { ===== begin morkProbeMap methods ===== 203 virtual mork_test // hit(a,b) implies hash(a) == hash(b) 204 MapTest(morkEnv* ev, const void* inMapKey, 205 const void* inAppKey) const override; 206 207 virtual mork_u4 // hit(a,b) implies hash(a) == hash(b) 208 MapHash(morkEnv* ev, const void* inAppKey) const override; 209 210 virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev, 211 const void* inMapKey) const override; 212 213 // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey); 214 215 // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' into all keys 216 // inside map 217 // void* ioMapKey, mork_count inKeyCount); // array of keys inside map 218 219 // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map 220 // const void* inAppKey, const void* inAppVal, // (key,val) outside map 221 // void* outMapKey, void* outMapVal); // (key,val) inside map 222 223 // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the 224 // map 225 // const void* inMapKey, const void* inMapVal, // (key,val) inside map 226 // void* outAppKey, void* outAppVal) const; // (key,val) outside map 227 // } ===== end morkProbeMap methods ===== 228 #else /*MORK_ENABLE_PROBE_MAPS*/ 229 // { ===== begin morkMap poly interface ===== 230 virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b) 231 Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const override; 232 // implemented using morkBookAtom::EqualFormAndBody() 233 234 virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b) 235 Hash(morkEnv* ev, const void* inKey) const override; 236 // implemented using morkBookAtom::HashFormAndBody() 237 // } ===== end morkMap poly interface ===== 238 #endif /*MORK_ENABLE_PROBE_MAPS*/ 239 240 public: // other map methods 241 mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom); 242 // AddAtom() returns ev->Good() 243 244 morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom); 245 // CutAtom() returns the atom removed equal to inAtom, if there was one 246 247 morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom); 248 // GetAtom() returns the atom equal to inAtom, or else nil 249 250 // note the atoms are owned elsewhere, usually by morkAtomSpace 251 252 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakAtomBodyMap(morkAtomBodyMap * me,morkEnv * ev,morkAtomBodyMap ** ioSlot)253 static void SlotWeakAtomBodyMap(morkAtomBodyMap* me, morkEnv* ev, 254 morkAtomBodyMap** ioSlot) { 255 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 256 } 257 SlotStrongAtomBodyMap(morkAtomBodyMap * me,morkEnv * ev,morkAtomBodyMap ** ioSlot)258 static void SlotStrongAtomBodyMap(morkAtomBodyMap* me, morkEnv* ev, 259 morkAtomBodyMap** ioSlot) { 260 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 261 } 262 }; 263 264 #ifdef MORK_ENABLE_PROBE_MAPS 265 class morkAtomBodyMapIter : public morkProbeMapIter { // typesafe wrapper class 266 #else /*MORK_ENABLE_PROBE_MAPS*/ 267 class morkAtomBodyMapIter : public morkMapIter { // typesafe wrapper class 268 #endif /*MORK_ENABLE_PROBE_MAPS*/ 269 270 public: 271 #ifdef MORK_ENABLE_PROBE_MAPS morkAtomBodyMapIter(morkEnv * ev,morkAtomBodyMap * ioMap)272 morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) 273 : morkProbeMapIter(ev, ioMap) {} 274 morkAtomBodyMapIter()275 morkAtomBodyMapIter() : morkProbeMapIter() {} 276 #else /*MORK_ENABLE_PROBE_MAPS*/ 277 morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) 278 : morkMapIter(ev, ioMap) {} 279 280 morkAtomBodyMapIter() : morkMapIter() {} 281 #endif /*MORK_ENABLE_PROBE_MAPS*/ 282 InitAtomBodyMapIter(morkEnv * ev,morkAtomBodyMap * ioMap)283 void InitAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap) { 284 this->InitMapIter(ev, ioMap); 285 } 286 FirstAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)287 mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 288 return this->First(ev, outAtomPtr, /*val*/ (void*)0); 289 } 290 NextAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)291 mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 292 return this->Next(ev, outAtomPtr, /*val*/ (void*)0); 293 } 294 HereAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)295 mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 296 return this->Here(ev, outAtomPtr, /*val*/ (void*)0); 297 } 298 CutHereAtom(morkEnv * ev,morkBookAtom ** outAtomPtr)299 mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr) { 300 return this->CutHere(ev, outAtomPtr, /*val*/ (void*)0); 301 } 302 }; 303 304 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 305 306 #define morkDerived_kAtomRowMap /*i*/ 0x6152 /* ascii 'aR' */ 307 308 /*| morkAtomRowMap: maps morkAtom* -> morkRow* 309 |*/ 310 class morkAtomRowMap : public morkIntMap { // for mapping atoms to rows 311 312 public: 313 mork_column mAtomRowMap_IndexColumn; // row column being indexed 314 315 public: 316 virtual ~morkAtomRowMap(); 317 morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 318 nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn); 319 320 public: // adding and cutting from morkRow instance candidate 321 void AddRow(morkEnv* ev, morkRow* ioRow); 322 // add ioRow only if it contains a cell in mAtomRowMap_IndexColumn. 323 324 void CutRow(morkEnv* ev, morkRow* ioRow); 325 // cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn. 326 327 public: // other map methods AddAid(morkEnv * ev,mork_aid inAid,morkRow * ioRow)328 mork_bool AddAid(morkEnv* ev, mork_aid inAid, morkRow* ioRow) { 329 return this->AddInt(ev, inAid, ioRow); 330 } 331 // the AddAid() boolean return equals ev->Good(). 332 CutAid(morkEnv * ev,mork_aid inAid)333 mork_bool CutAid(morkEnv* ev, mork_aid inAid) { 334 return this->CutInt(ev, inAid); 335 } 336 // The CutAid() boolean return indicates whether removal happened. 337 GetAid(morkEnv * ev,mork_aid inAid)338 morkRow* GetAid(morkEnv* ev, mork_aid inAid) { 339 return (morkRow*)this->GetInt(ev, inAid); 340 } 341 // Note the returned space does NOT have an increase in refcount for this. 342 343 public: // dynamic type identification IsAtomRowMap()344 mork_bool IsAtomRowMap() const { 345 return IsNode() && mNode_Derived == morkDerived_kAtomRowMap; 346 } 347 348 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakAtomRowMap(morkAtomRowMap * me,morkEnv * ev,morkAtomRowMap ** ioSlot)349 static void SlotWeakAtomRowMap(morkAtomRowMap* me, morkEnv* ev, 350 morkAtomRowMap** ioSlot) { 351 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 352 } 353 SlotStrongAtomRowMap(morkAtomRowMap * me,morkEnv * ev,morkAtomRowMap ** ioSlot)354 static void SlotStrongAtomRowMap(morkAtomRowMap* me, morkEnv* ev, 355 morkAtomRowMap** ioSlot) { 356 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 357 } 358 }; 359 360 class morkAtomRowMapIter : public morkMapIter { // typesafe wrapper class 361 362 public: morkAtomRowMapIter(morkEnv * ev,morkAtomRowMap * ioMap)363 morkAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap) 364 : morkMapIter(ev, ioMap) {} 365 morkAtomRowMapIter()366 morkAtomRowMapIter() : morkMapIter() {} InitAtomRowMapIter(morkEnv * ev,morkAtomRowMap * ioMap)367 void InitAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap) { 368 this->InitMapIter(ev, ioMap); 369 } 370 FirstAtomAndRow(morkEnv * ev,morkAtom ** outAtom,morkRow ** outRow)371 mork_change* FirstAtomAndRow(morkEnv* ev, morkAtom** outAtom, 372 morkRow** outRow) { 373 return this->First(ev, outAtom, outRow); 374 } 375 NextAtomAndRow(morkEnv * ev,morkAtom ** outAtom,morkRow ** outRow)376 mork_change* NextAtomAndRow(morkEnv* ev, morkAtom** outAtom, 377 morkRow** outRow) { 378 return this->Next(ev, outAtom, outRow); 379 } 380 HereAtomAndRow(morkEnv * ev,morkAtom ** outAtom,morkRow ** outRow)381 mork_change* HereAtomAndRow(morkEnv* ev, morkAtom** outAtom, 382 morkRow** outRow) { 383 return this->Here(ev, outAtom, outRow); 384 } 385 CutHereAtomAndRow(morkEnv * ev,morkAtom ** outAtom,morkRow ** outRow)386 mork_change* CutHereAtomAndRow(morkEnv* ev, morkAtom** outAtom, 387 morkRow** outRow) { 388 return this->CutHere(ev, outAtom, outRow); 389 } 390 }; 391 392 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 393 394 #endif /* _MORKATOMMAP_ */ 395