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