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 _MORKMAP_
19 # include "morkMap.h"
20 #endif
21
22 #ifndef _MORKSPACE_
23 # include "morkSpace.h"
24 #endif
25
26 #ifndef _MORKENV_
27 # include "morkEnv.h"
28 #endif
29
30 #ifndef _MORKSPACE_
31 # include "morkSpace.h"
32 #endif
33
34 #ifndef _MORKATOMSPACE_
35 # include "morkAtomSpace.h"
36 #endif
37
38 #ifndef _MORKPOOL_
39 # include "morkPool.h"
40 #endif
41
42 #ifndef _MORKSTORE_
43 # include "morkStore.h"
44 #endif
45
46 #ifndef _MORKATOM_
47 # include "morkAtom.h"
48 #endif
49
50 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
51
52 // ````` ````` ````` ````` `````
53 // { ===== begin morkNode interface =====
54
CloseMorkNode(morkEnv * ev)55 /*public virtual*/ void morkAtomSpace::CloseMorkNode(
56 morkEnv* ev) // CloseAtomSpace() only if open
57 {
58 if (this->IsOpenNode()) {
59 this->MarkClosing();
60 this->CloseAtomSpace(ev);
61 this->MarkShut();
62 }
63 }
64
65 /*public virtual*/
~morkAtomSpace()66 morkAtomSpace::~morkAtomSpace() // assert CloseAtomSpace() executed earlier
67 {
68 MORK_ASSERT(mAtomSpace_HighUnderId == 0);
69 MORK_ASSERT(mAtomSpace_HighOverId == 0);
70 MORK_ASSERT(this->IsShutNode());
71 MORK_ASSERT(mAtomSpace_AtomAids.IsShutNode());
72 MORK_ASSERT(mAtomSpace_AtomBodies.IsShutNode());
73 }
74
75 /*public non-poly*/
morkAtomSpace(morkEnv * ev,const morkUsage & inUsage,mork_scope inScope,morkStore * ioStore,nsIMdbHeap * ioHeap,nsIMdbHeap * ioSlotHeap)76 morkAtomSpace::morkAtomSpace(morkEnv* ev, const morkUsage& inUsage,
77 mork_scope inScope, morkStore* ioStore,
78 nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
79 : morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap),
80 mAtomSpace_HighUnderId(morkAtomSpace_kMinUnderId),
81 mAtomSpace_HighOverId(morkAtomSpace_kMinOverId),
82 mAtomSpace_AtomAids(ev, morkUsage::kMember, (nsIMdbHeap*)0, ioSlotHeap),
83 mAtomSpace_AtomBodies(ev, morkUsage::kMember, (nsIMdbHeap*)0,
84 ioSlotHeap) {
85 // the morkSpace base constructor handles any dirty propagation
86 if (ev->Good()) mNode_Derived = morkDerived_kAtomSpace;
87 }
88
CloseAtomSpace(morkEnv * ev)89 /*public non-poly*/ void morkAtomSpace::CloseAtomSpace(
90 morkEnv* ev) // called by CloseMorkNode();
91 {
92 if (this->IsNode()) {
93 mAtomSpace_AtomBodies.CloseMorkNode(ev);
94 morkStore* store = mSpace_Store;
95 if (store) this->CutAllAtoms(ev, &store->mStore_Pool);
96
97 mAtomSpace_AtomAids.CloseMorkNode(ev);
98 this->CloseSpace(ev);
99 mAtomSpace_HighUnderId = 0;
100 mAtomSpace_HighOverId = 0;
101 this->MarkShut();
102 } else
103 this->NonNodeError(ev);
104 }
105
106 // } ===== end morkNode methods =====
107 // ````` ````` ````` ````` `````
108
NonAtomSpaceTypeError(morkEnv * ev)109 /*static*/ void morkAtomSpace::NonAtomSpaceTypeError(morkEnv* ev) {
110 ev->NewError("non morkAtomSpace");
111 }
112
CutAllAtoms(morkEnv * ev,morkPool * ioPool)113 mork_num morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool) {
114 #ifdef MORK_ENABLE_ZONE_ARENAS
115 MORK_USED_2(ev, ioPool);
116 return 0;
117 #else /*MORK_ENABLE_ZONE_ARENAS*/
118 if (this->IsAtomSpaceClean()) this->MaybeDirtyStoreAndSpace();
119
120 mork_num outSlots = mAtomSpace_AtomAids.MapFill();
121 morkBookAtom* a = 0; // old key atom in the map
122
123 morkStore* store = mSpace_Store;
124 mork_change* c = 0;
125 morkAtomAidMapIter i(ev, &mAtomSpace_AtomAids);
126 for (c = i.FirstAtom(ev, &a); c; c = i.NextAtom(ev, &a)) {
127 if (a) ioPool->ZapAtom(ev, a, &store->mStore_Zone);
128
129 # ifdef MORK_ENABLE_PROBE_MAPS
130 // do not cut anything from the map
131 # else /*MORK_ENABLE_PROBE_MAPS*/
132 i.CutHereAtom(ev, /*key*/ (morkBookAtom**)0);
133 # endif /*MORK_ENABLE_PROBE_MAPS*/
134 }
135
136 return outSlots;
137 #endif /*MORK_ENABLE_ZONE_ARENAS*/
138 }
139
MakeBookAtomCopyWithAid(morkEnv * ev,const morkFarBookAtom & inAtom,mork_aid inAid)140 morkBookAtom* morkAtomSpace::MakeBookAtomCopyWithAid(
141 morkEnv* ev, const morkFarBookAtom& inAtom, mork_aid inAid)
142 // Make copy of inAtom and put it in both maps, using specified ID.
143 {
144 morkBookAtom* outAtom = 0;
145 morkStore* store = mSpace_Store;
146 if (ev->Good() && store) {
147 morkPool* pool = this->GetSpaceStorePool();
148 outAtom = pool->NewFarBookAtomCopy(ev, inAtom, &store->mStore_Zone);
149 if (outAtom) {
150 if (store->mStore_CanDirty) {
151 outAtom->SetAtomDirty();
152 if (this->IsAtomSpaceClean()) this->MaybeDirtyStoreAndSpace();
153 }
154
155 outAtom->mBookAtom_Id = inAid;
156 outAtom->mBookAtom_Space = this;
157 mAtomSpace_AtomAids.AddAtom(ev, outAtom);
158 mAtomSpace_AtomBodies.AddAtom(ev, outAtom);
159 if (this->SpaceScope() == morkAtomSpace_kColumnScope)
160 outAtom->MakeCellUseForever(ev);
161
162 if (mAtomSpace_HighUnderId <= inAid) mAtomSpace_HighUnderId = inAid + 1;
163 }
164 }
165 return outAtom;
166 }
167
MakeBookAtomCopy(morkEnv * ev,const morkFarBookAtom & inAtom)168 morkBookAtom* morkAtomSpace::MakeBookAtomCopy(morkEnv* ev,
169 const morkFarBookAtom& inAtom)
170 // make copy of inAtom and put it in both maps, using a new ID as needed.
171 {
172 morkBookAtom* outAtom = 0;
173 morkStore* store = mSpace_Store;
174 if (ev->Good() && store) {
175 if (store->mStore_CanAutoAssignAtomIdentity) {
176 morkPool* pool = this->GetSpaceStorePool();
177 morkBookAtom* atom =
178 pool->NewFarBookAtomCopy(ev, inAtom, &mSpace_Store->mStore_Zone);
179 if (atom) {
180 mork_aid id = this->MakeNewAtomId(ev, atom);
181 if (id) {
182 if (store->mStore_CanDirty) {
183 atom->SetAtomDirty();
184 if (this->IsAtomSpaceClean()) this->MaybeDirtyStoreAndSpace();
185 }
186
187 outAtom = atom;
188 atom->mBookAtom_Space = this;
189 mAtomSpace_AtomAids.AddAtom(ev, atom);
190 mAtomSpace_AtomBodies.AddAtom(ev, atom);
191 if (this->SpaceScope() == morkAtomSpace_kColumnScope)
192 outAtom->MakeCellUseForever(ev);
193 } else
194 pool->ZapAtom(ev, atom, &mSpace_Store->mStore_Zone);
195 }
196 } else
197 mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
198 }
199 return outAtom;
200 }
201
MakeNewAtomId(morkEnv * ev,morkBookAtom * ioAtom)202 mork_aid morkAtomSpace::MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom) {
203 mork_aid outAid = 0;
204 mork_tid id = mAtomSpace_HighUnderId;
205 mork_num count = 8; // try up to eight times
206
207 while (!outAid && count) // still trying to find an unused table ID?
208 {
209 --count;
210 ioAtom->mBookAtom_Id = id;
211 if (!mAtomSpace_AtomAids.GetAtom(ev, ioAtom))
212 outAid = id;
213 else {
214 MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems
215 ++id;
216 }
217 }
218
219 mAtomSpace_HighUnderId = id + 1;
220 return outAid;
221 }
222
223 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
224
~morkAtomSpaceMap()225 morkAtomSpaceMap::~morkAtomSpaceMap() {}
226
morkAtomSpaceMap(morkEnv * ev,const morkUsage & inUsage,nsIMdbHeap * ioHeap,nsIMdbHeap * ioSlotHeap)227 morkAtomSpaceMap::morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage,
228 nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
229 : morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap) {
230 if (ev->Good()) mNode_Derived = morkDerived_kAtomSpaceMap;
231 }
232
233 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
234