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 _MORKROWSPACE_ 7 #define _MORKROWSPACE_ 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 _MORKNODEMAP_ 22 # include "morkNodeMap.h" 23 #endif 24 25 #ifndef _MORKROWMAP_ 26 # include "morkRowMap.h" 27 #endif 28 29 #ifndef _MORKTABLE_ 30 # include "morkTable.h" 31 #endif 32 33 #ifndef _MORKARRAY_ 34 # include "morkArray.h" 35 #endif 36 37 #ifndef _MORKDEQUE_ 38 # include "morkDeque.h" 39 #endif 40 41 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 42 43 #define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */ 44 45 #define morkRowSpace_kStartRowMapSlotCount 11 46 47 #define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */ 48 #define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */ 49 50 class morkAtomRowMap; 51 52 /*| morkRowSpace: 53 |*/ 54 class morkRowSpace : public morkSpace { // 55 56 // public: // slots inherited from morkSpace (meant to inform only) 57 // nsIMdbHeap* mNode_Heap; 58 59 // mork_base mNode_Base; // must equal morkBase_kNode 60 // mork_derived mNode_Derived; // depends on specific node subclass 61 62 // mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead 63 // mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone 64 // mork_able mNode_Mutable; // can this node be modified? 65 // mork_load mNode_Load; // is this node clean or dirty? 66 67 // mork_uses mNode_Uses; // refcount for strong refs 68 // mork_refs mNode_Refs; // refcount for strong refs + weak refs 69 70 // morkStore* mSpace_Store; // weak ref to containing store 71 72 // mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs 73 // mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs 74 // mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment 75 76 public: // state is public because the entire Mork system is private 77 nsIMdbHeap* mRowSpace_SlotHeap; 78 79 #ifdef MORK_ENABLE_PROBE_MAPS 80 morkRowProbeMap mRowSpace_Rows; // hash table of morkRow instances 81 #else /*MORK_ENABLE_PROBE_MAPS*/ 82 morkRowMap mRowSpace_Rows; // hash table of morkRow instances 83 #endif /*MORK_ENABLE_PROBE_MAPS*/ 84 morkTableMap mRowSpace_Tables; // all the tables in this row scope 85 86 mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs 87 mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs 88 89 mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist 90 91 // every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap: 92 morkAtomRowMap* mRowSpace_IndexCache[morkRowSpace_kPrimeCacheSize]; 93 94 morkDeque mRowSpace_TablesByPriority[morkPriority_kCount]; 95 96 public: // more specific dirty methods for row space: SetRowSpaceDirty()97 void SetRowSpaceDirty() { this->SetNodeDirty(); } SetRowSpaceClean()98 void SetRowSpaceClean() { this->SetNodeClean(); } 99 IsRowSpaceClean()100 mork_bool IsRowSpaceClean() const { return this->IsNodeClean(); } IsRowSpaceDirty()101 mork_bool IsRowSpaceDirty() const { return this->IsNodeDirty(); } 102 103 // { ===== begin morkNode interface ===== 104 public: // morkNode virtual methods 105 virtual void CloseMorkNode( 106 morkEnv* ev) override; // CloseRowSpace() only if open 107 virtual ~morkRowSpace(); // assert that CloseRowSpace() executed earlier 108 109 public: // morkMap construction & destruction 110 morkRowSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope, 111 morkStore* ioStore, nsIMdbHeap* ioNodeHeap, 112 nsIMdbHeap* ioSlotHeap); 113 void CloseRowSpace(morkEnv* ev); // called by CloseMorkNode(); 114 115 public: // dynamic type identification IsRowSpace()116 mork_bool IsRowSpace() const { 117 return IsNode() && mNode_Derived == morkDerived_kRowSpace; 118 } 119 // } ===== end morkNode methods ===== 120 121 public: // typing 122 static void NonRowSpaceTypeError(morkEnv* ev); 123 static void ZeroScopeError(morkEnv* ev); 124 static void ZeroKindError(morkEnv* ev); 125 static void ZeroTidError(morkEnv* ev); 126 static void MinusOneRidError(morkEnv* ev); 127 128 // static void ExpectAutoIdOnlyError(morkEnv* ev); 129 // static void ExpectAutoIdNeverError(morkEnv* ev); 130 131 public: // other space methods 132 mork_num CutAllRows(morkEnv* ev, morkPool* ioPool); 133 // CutAllRows() puts all rows and cells back into the pool. 134 135 morkTable* NewTable(morkEnv* ev, mork_kind inTableKind, 136 mdb_bool inMustBeUnique, 137 const mdbOid* inOptionalMetaRowOid); 138 139 morkTable* NewTableWithTid(morkEnv* ev, mork_tid inTid, mork_kind inTableKind, 140 const mdbOid* inOptionalMetaRowOid); 141 142 morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind); FindTableByTid(morkEnv * ev,mork_tid inTid)143 morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid) { 144 return mRowSpace_Tables.GetTable(ev, inTid); 145 } 146 147 mork_tid MakeNewTableId(morkEnv* ev); 148 mork_rid MakeNewRowId(morkEnv* ev); 149 150 // morkRow* FindRowByRid(morkEnv* ev, mork_rid inRid) 151 // { return (morkRow*) mRowSpace_Rows.GetRow(ev, inRid); } 152 153 morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid); 154 morkRow* NewRow(morkEnv* ev); 155 156 morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn); 157 158 morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn); 159 morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn); 160 161 protected: // internal utilities 162 morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn); 163 164 public: // typesafe refcounting inlines calling inherited morkNode methods SlotWeakRowSpace(morkRowSpace * me,morkEnv * ev,morkRowSpace ** ioSlot)165 static void SlotWeakRowSpace(morkRowSpace* me, morkEnv* ev, 166 morkRowSpace** ioSlot) { 167 morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot); 168 } 169 SlotStrongRowSpace(morkRowSpace * me,morkEnv * ev,morkRowSpace ** ioSlot)170 static void SlotStrongRowSpace(morkRowSpace* me, morkEnv* ev, 171 morkRowSpace** ioSlot) { 172 morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot); 173 } 174 }; 175 176 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 177 178 #define morkDerived_kRowSpaceMap /*i*/ 0x725A /* ascii 'rZ' */ 179 180 /*| morkRowSpaceMap: maps mork_scope -> morkRowSpace 181 |*/ 182 class morkRowSpaceMap : public morkNodeMap { // for mapping tokens to tables 183 184 public: 185 virtual ~morkRowSpaceMap(); 186 morkRowSpaceMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap, 187 nsIMdbHeap* ioSlotHeap); 188 189 public: // other map methods AddRowSpace(morkEnv * ev,morkRowSpace * ioRowSpace)190 mork_bool AddRowSpace(morkEnv* ev, morkRowSpace* ioRowSpace) { 191 return this->AddNode(ev, ioRowSpace->SpaceScope(), ioRowSpace); 192 } 193 // the AddRowSpace() boolean return equals ev->Good(). 194 CutRowSpace(morkEnv * ev,mork_scope inScope)195 mork_bool CutRowSpace(morkEnv* ev, mork_scope inScope) { 196 return this->CutNode(ev, inScope); 197 } 198 // The CutRowSpace() boolean return indicates whether removal happened. 199 GetRowSpace(morkEnv * ev,mork_scope inScope)200 morkRowSpace* GetRowSpace(morkEnv* ev, mork_scope inScope) { 201 return (morkRowSpace*)this->GetNode(ev, inScope); 202 } 203 // Note the returned space does NOT have an increase in refcount for this. 204 CutAllRowSpaces(morkEnv * ev)205 mork_num CutAllRowSpaces(morkEnv* ev) { return this->CutAllNodes(ev); } 206 // CutAllRowSpaces() releases all the referenced table values. 207 }; 208 209 class morkRowSpaceMapIter : public morkMapIter { // typesafe wrapper class 210 211 public: morkRowSpaceMapIter(morkEnv * ev,morkRowSpaceMap * ioMap)212 morkRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap) 213 : morkMapIter(ev, ioMap) {} 214 morkRowSpaceMapIter()215 morkRowSpaceMapIter() : morkMapIter() {} InitRowSpaceMapIter(morkEnv * ev,morkRowSpaceMap * ioMap)216 void InitRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap) { 217 this->InitMapIter(ev, ioMap); 218 } 219 FirstRowSpace(morkEnv * ev,mork_scope * outScope,morkRowSpace ** outRowSpace)220 mork_change* FirstRowSpace(morkEnv* ev, mork_scope* outScope, 221 morkRowSpace** outRowSpace) { 222 return this->First(ev, outScope, outRowSpace); 223 } 224 NextRowSpace(morkEnv * ev,mork_scope * outScope,morkRowSpace ** outRowSpace)225 mork_change* NextRowSpace(morkEnv* ev, mork_scope* outScope, 226 morkRowSpace** outRowSpace) { 227 return this->Next(ev, outScope, outRowSpace); 228 } 229 HereRowSpace(morkEnv * ev,mork_scope * outScope,morkRowSpace ** outRowSpace)230 mork_change* HereRowSpace(morkEnv* ev, mork_scope* outScope, 231 morkRowSpace** outRowSpace) { 232 return this->Here(ev, outScope, outRowSpace); 233 } 234 CutHereRowSpace(morkEnv * ev,mork_scope * outScope,morkRowSpace ** outRowSpace)235 mork_change* CutHereRowSpace(morkEnv* ev, mork_scope* outScope, 236 morkRowSpace** outRowSpace) { 237 return this->CutHere(ev, outScope, outRowSpace); 238 } 239 }; 240 241 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 242 243 #endif /* _MORKROWSPACE_ */ 244