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 _MORKATOMSPACE_ 7 #define _MORKATOMSPACE_ 1 8 9 #ifndef _MORK_ 10 # include "mork.h" 11 #endif 12 13 #ifndef _MORKNODE_ 14 # include "morkNode.h" 15 #endif 16 17 #ifndef _MORKSPACE_ 18 # include "morkSpace.h" 19 #endif 20 21 #ifndef _MORKATOMMAP_ 22 # include "morkAtomMap.h" 23 #endif 24 25 #ifndef _MORKNODEMAP_ 26 # include "morkNodeMap.h" 27 #endif 28 29 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 30 31 /*| kMinUnderId: the smallest ID we auto-assign to the 'under' namespace 32 **| reserved for tokens expected to occur very frequently, such as the names 33 **| of columns. We reserve single byte ids in the ASCII range to correspond 34 **| one-to-one to those tokens consisting single ASCII characters (so that 35 **| this assignment is always known and constant). So we start at 0x80, and 36 **| then reserve the upper half of two hex digit ids and all the three hex 37 **| digit IDs for the 'under' namespace for common tokens. 38 |*/ 39 #define morkAtomSpace_kMinUnderId 0x80 /* low 7 bits mean byte tokens */ 40 41 #define morkAtomSpace_kMaxSevenBitAid 0x7F /* low seven bit integer ID */ 42 43 /*| kMinOverId: the smallest ID we auto-assign to the 'over' namespace that 44 **| might include very large numbers of tokens that are used infrequently, 45 **| so that we care less whether the shortest hex representation is used. 46 **| So we start all IDs for 'over' category tokens at a value range that 47 **| needs at least four hex digits, so we can reserve three hex digits and 48 **| shorter for more commonly occurring tokens in the 'under' category. 49 |*/ 50 #define morkAtomSpace_kMinOverId 0x1000 /* using at least four hex bytes */ 51 52 #define morkDerived_kAtomSpace /*i*/ 0x6153 /* ascii 'aS' */ 53 54 #define morkAtomSpace_kColumnScope \ 55 ((mork_scope)'c') /* column scope is forever */ 56 57 /*| morkAtomSpace: 58 |*/ 59 class morkAtomSpace : public morkSpace { // 60 61 // public: // slots inherited from morkSpace (meant to inform only) 62 // nsIMdbHeap* mNode_Heap; 63 64 // mork_base mNode_Base; // must equal morkBase_kNode 65 // mork_derived mNode_Derived; // depends on specific node subclass 66 67 // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead 68 // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone 69 // mork_able mNode_Mutable; // can this node be modified? 70 // mork_load mNode_Load; // is this node clean or dirty? 71 72 // mork_uses mNode_Uses; // refcount for strong refs 73 // mork_refs mNode_Refs; // refcount for strong refs + weak refs 74 75 // morkStore* mSpace_Store; // weak ref to containing store 76 77 // mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs 78 // mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs 79 // mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment 80 81 public: // state is public because the entire Mork system is private 82 mork_aid mAtomSpace_HighUnderId; // high ID in 'under' range 83 mork_aid mAtomSpace_HighOverId; // high ID in 'over' range 84 85 morkAtomAidMap mAtomSpace_AtomAids; // all atoms in space by ID 86 morkAtomBodyMap mAtomSpace_AtomBodies; // all atoms in space by body 87 88 public: // more specific dirty methods for atom space: SetAtomSpaceDirty()89 void SetAtomSpaceDirty() { this->SetNodeDirty(); } SetAtomSpaceClean()90 void SetAtomSpaceClean() { this->SetNodeClean(); } 91 IsAtomSpaceClean()92 mork_bool IsAtomSpaceClean() const { return this->IsNodeClean(); } IsAtomSpaceDirty()93 mork_bool IsAtomSpaceDirty() const { return this->IsNodeDirty(); } 94 95 // { ===== begin morkNode interface ===== 96 public: // morkNode virtual methods 97 virtual void CloseMorkNode( 98 morkEnv* ev) override; // CloseAtomSpace() only if open 99 virtual ~morkAtomSpace(); // assert that CloseAtomSpace() executed earlier 100 101 public: // morkMap construction & destruction 102 morkAtomSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope, 103 morkStore* ioStore, nsIMdbHeap* ioNodeHeap, 104 nsIMdbHeap* ioSlotHeap); 105 void CloseAtomSpace(morkEnv* ev); // called by CloseMorkNode(); 106 107 public: // dynamic type identification IsAtomSpace()108 mork_bool IsAtomSpace() const { 109 return IsNode() && mNode_Derived == morkDerived_kAtomSpace; 110 } 111 // } ===== end morkNode methods ===== 112 113 public: // typing 114 void NonAtomSpaceTypeError(morkEnv* ev); 115 116 public: // setup 117 mork_bool MarkAllAtomSpaceContentDirty(morkEnv* ev); 118 // MarkAllAtomSpaceContentDirty() visits every space object and marks 119 // them dirty, including every table, row, cell, and atom. The return 120 // equals ev->Good(), to show whether any error happened. This method is 121 // intended for use in the beginning of a "compress commit" which writes 122 // all store content, whether dirty or not. We dirty everything first so 123 // that later iterations over content can mark things clean as they are 124 // written, and organize the process of serialization so that objects are 125 // written only at need (because of being dirty). 126 127 public: // other space methods 128 // void ReserveColumnAidCount(mork_count inCount) 129 // { 130 // mAtomSpace_HighUnderId = morkAtomSpace_kMinUnderId + inCount; 131 // mAtomSpace_HighOverId = morkAtomSpace_kMinOverId + inCount; 132 // } 133 134 mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool); 135 // CutAllAtoms() puts all the atoms back in the pool. 136 137 morkBookAtom* MakeBookAtomCopyWithAid(morkEnv* ev, 138 const morkFarBookAtom& inAtom, 139 mork_aid inAid); 140 // Make copy of inAtom and put it in both maps, using specified ID. 141 142 morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom); 143 // Make copy of inAtom and put it in both maps, using a new ID as needed. 144 145 mork_aid MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom); 146 // generate an unused atom id. 147 148 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakAtomSpace(morkAtomSpace * me,morkEnv * ev,morkAtomSpace ** ioSlot)149 static void SlotWeakAtomSpace(morkAtomSpace* me, morkEnv* ev, 150 morkAtomSpace** ioSlot) { 151 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 152 } 153 SlotStrongAtomSpace(morkAtomSpace * me,morkEnv * ev,morkAtomSpace ** ioSlot)154 static void SlotStrongAtomSpace(morkAtomSpace* me, morkEnv* ev, 155 morkAtomSpace** ioSlot) { 156 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 157 } 158 }; 159 160 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 161 162 #define morkDerived_kAtomSpaceMap /*i*/ 0x615A /* ascii 'aZ' */ 163 164 /*| morkAtomSpaceMap: maps mork_scope -> morkAtomSpace 165 |*/ 166 class morkAtomSpaceMap : public morkNodeMap { // for mapping tokens to tables 167 168 public: 169 virtual ~morkAtomSpaceMap(); 170 morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 171 nsIMdbHeap* ioSlotHeap); 172 173 public: // other map methods AddAtomSpace(morkEnv * ev,morkAtomSpace * ioAtomSpace)174 mork_bool AddAtomSpace(morkEnv* ev, morkAtomSpace* ioAtomSpace) { 175 return this->AddNode(ev, ioAtomSpace->SpaceScope(), ioAtomSpace); 176 } 177 // the AddAtomSpace() boolean return equals ev->Good(). 178 CutAtomSpace(morkEnv * ev,mork_scope inScope)179 mork_bool CutAtomSpace(morkEnv* ev, mork_scope inScope) { 180 return this->CutNode(ev, inScope); 181 } 182 // The CutAtomSpace() boolean return indicates whether removal happened. 183 GetAtomSpace(morkEnv * ev,mork_scope inScope)184 morkAtomSpace* GetAtomSpace(morkEnv* ev, mork_scope inScope) { 185 return (morkAtomSpace*)this->GetNode(ev, inScope); 186 } 187 // Note the returned space does NOT have an increase in refcount for this. 188 CutAllAtomSpaces(morkEnv * ev)189 mork_num CutAllAtomSpaces(morkEnv* ev) { return this->CutAllNodes(ev); } 190 // CutAllAtomSpaces() releases all the referenced table values. 191 }; 192 193 class morkAtomSpaceMapIter : public morkMapIter { // typesafe wrapper class 194 195 public: morkAtomSpaceMapIter(morkEnv * ev,morkAtomSpaceMap * ioMap)196 morkAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap) 197 : morkMapIter(ev, ioMap) {} 198 morkAtomSpaceMapIter()199 morkAtomSpaceMapIter() : morkMapIter() {} InitAtomSpaceMapIter(morkEnv * ev,morkAtomSpaceMap * ioMap)200 void InitAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap) { 201 this->InitMapIter(ev, ioMap); 202 } 203 FirstAtomSpace(morkEnv * ev,mork_scope * outScope,morkAtomSpace ** outAtomSpace)204 mork_change* FirstAtomSpace(morkEnv* ev, mork_scope* outScope, 205 morkAtomSpace** outAtomSpace) { 206 return this->First(ev, outScope, outAtomSpace); 207 } 208 NextAtomSpace(morkEnv * ev,mork_scope * outScope,morkAtomSpace ** outAtomSpace)209 mork_change* NextAtomSpace(morkEnv* ev, mork_scope* outScope, 210 morkAtomSpace** outAtomSpace) { 211 return this->Next(ev, outScope, outAtomSpace); 212 } 213 HereAtomSpace(morkEnv * ev,mork_scope * outScope,morkAtomSpace ** outAtomSpace)214 mork_change* HereAtomSpace(morkEnv* ev, mork_scope* outScope, 215 morkAtomSpace** outAtomSpace) { 216 return this->Here(ev, outScope, outAtomSpace); 217 } 218 CutHereAtomSpace(morkEnv * ev,mork_scope * outScope,morkAtomSpace ** outAtomSpace)219 mork_change* CutHereAtomSpace(morkEnv* ev, mork_scope* outScope, 220 morkAtomSpace** outAtomSpace) { 221 return this->CutHere(ev, outScope, outAtomSpace); 222 } 223 }; 224 225 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 226 227 #endif /* _MORKATOMSPACE_ */ 228