1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
58 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
60 // ````` ````` ````` ````` `````
61 // { ===== begin morkNode interface =====
63 /*public virtual*/ void
64 morkBead::CloseMorkNode(morkEnv
* ev
) // CloseBead() only if open
66 if ( this->IsOpenNode() )
75 morkBead::~morkBead() // assert CloseBead() executed earlier
77 MORK_ASSERT(mBead_Color
==0 || mNode_Usage
== morkUsage_kStack
);
81 morkBead::morkBead(mork_color inBeadColor
)
82 : morkNode( morkUsage_kStack
)
83 , mBead_Color( inBeadColor
)
88 morkBead::morkBead(const morkUsage
& inUsage
, nsIMdbHeap
* ioHeap
,
89 mork_color inBeadColor
)
90 : morkNode( inUsage
, ioHeap
)
91 , mBead_Color( inBeadColor
)
96 morkBead::morkBead(morkEnv
* ev
,
97 const morkUsage
& inUsage
, nsIMdbHeap
* ioHeap
, mork_color inBeadColor
)
98 : morkNode(ev
, inUsage
, ioHeap
)
99 , mBead_Color( inBeadColor
)
104 mNode_Derived
= morkDerived_kBead
;
108 /*public non-poly*/ void
109 morkBead::CloseBead(morkEnv
* ev
) // called by CloseMorkNode();
113 if ( this->IsNode() )
115 if ( !this->IsShutNode() )
122 this->NonNodeError(ev
);
125 ev
->NilPointerError();
128 // } ===== end morkNode methods =====
129 // ````` ````` ````` ````` `````
131 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
133 // ````` ````` ````` ````` `````
134 // { ===== begin morkNode interface =====
136 /*public virtual*/ void
137 morkBeadMap::CloseMorkNode(morkEnv
* ev
) // CloseBeadMap() only if open
139 if ( this->IsOpenNode() )
142 this->CloseBeadMap(ev
);
148 morkBeadMap::~morkBeadMap() // assert CloseBeadMap() executed earlier
150 MORK_ASSERT(this->IsShutNode());
154 morkBeadMap::morkBeadMap(morkEnv
* ev
,
155 const morkUsage
& inUsage
, nsIMdbHeap
* ioHeap
, nsIMdbHeap
* ioSlotHeap
)
156 : morkMap(ev
, inUsage
, ioHeap
, sizeof(morkBead
*), /*inValSize*/ 0,
157 /*slotCount*/ 11, ioSlotHeap
, /*holdChanges*/ morkBool_kFalse
)
160 mNode_Derived
= morkDerived_kBeadMap
;
163 /*public non-poly*/ void
164 morkBeadMap::CloseBeadMap(morkEnv
* ev
) // called by CloseMorkNode();
168 if ( this->IsNode() )
170 this->CutAllBeads(ev
);
175 this->NonNodeError(ev
);
178 ev
->NilPointerError();
181 // } ===== end morkNode methods =====
182 // ````` ````` ````` ````` `````
185 morkBeadMap::AddBead(morkEnv
* ev
, morkBead
* ioBead
)
186 // the AddBead() boolean return equals ev->Good().
188 if ( ioBead
&& ev
->Good() )
190 morkBead
* oldBead
= 0; // old key in the map
192 mork_bool put
= this->Put(ev
, &ioBead
, /*val*/ (void*) 0,
193 /*key*/ &oldBead
, /*val*/ (void*) 0, (mork_change
**) 0);
195 if ( put
) // replaced an existing key?
197 if ( oldBead
!= ioBead
) // new bead was not already in table?
198 ioBead
->AddStrongRef(ev
); // now there's another ref
200 if ( oldBead
&& oldBead
!= ioBead
) // need to release old node?
201 oldBead
->CutStrongRef(ev
);
204 ioBead
->AddStrongRef(ev
); // another ref if not already in table
207 ev
->NilPointerError();
213 morkBeadMap::CutBead(morkEnv
* ev
, mork_color inColor
)
215 morkBead
* oldBead
= 0; // old key in the map
216 morkBead
bead(inColor
);
217 morkBead
* key
= &bead
;
219 mork_bool outCutNode
= this->Cut(ev
, &key
,
220 /*key*/ &oldBead
, /*val*/ (void*) 0, (mork_change
**) 0);
223 oldBead
->CutStrongRef(ev
);
230 morkBeadMap::GetBead(morkEnv
* ev
, mork_color inColor
)
231 // Note the returned bead does NOT have an increase in refcount for this.
233 morkBead
* oldBead
= 0; // old key in the map
234 morkBead
bead(inColor
);
235 morkBead
* key
= &bead
;
237 this->Get(ev
, &key
, /*key*/ &oldBead
, /*val*/ (void*) 0, (mork_change
**) 0);
244 morkBeadMap::CutAllBeads(morkEnv
* ev
)
245 // CutAllBeads() releases all the referenced beads.
247 mork_num outSlots
= mMap_Slots
;
249 morkBeadMapIter
i(ev
, this);
250 morkBead
* b
= i
.FirstBead(ev
);
263 // { ===== begin morkMap poly interface =====
264 /*virtual*/ mork_bool
265 morkBeadMap::Equal(morkEnv
* ev
, const void* inKeyA
, const void* inKeyB
) const
268 return (*(const morkBead
**) inKeyA
)->BeadEqual(
269 *(const morkBead
**) inKeyB
);
273 morkBeadMap::Hash(morkEnv
* ev
, const void* inKey
) const
276 return (*(const morkBead
**) inKey
)->BeadHash();
278 // } ===== end morkMap poly interface =====
281 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
284 morkBead
* morkBeadMapIter::FirstBead(morkEnv
* ev
)
287 this->First(ev
, &bead
, /*val*/ (void*) 0);
291 morkBead
* morkBeadMapIter::NextBead(morkEnv
* ev
)
294 this->Next(ev
, &bead
, /*val*/ (void*) 0);
298 morkBead
* morkBeadMapIter::HereBead(morkEnv
* ev
)
301 this->Here(ev
, &bead
, /*val*/ (void*) 0);
305 void morkBeadMapIter::CutHereBead(morkEnv
* ev
)
307 this->CutHere(ev
, /*key*/ (void*) 0, /*val*/ (void*) 0);
310 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
312 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
314 // ````` ````` ````` ````` `````
315 // { ===== begin morkNode interface =====
317 /*public virtual*/ void
318 morkBeadProbeMap::CloseMorkNode(morkEnv
* ev
) // CloseBeadProbeMap() if open
320 if ( this->IsOpenNode() )
323 this->CloseBeadProbeMap(ev
);
329 morkBeadProbeMap::~morkBeadProbeMap() // assert CloseBeadProbeMap() earlier
331 MORK_ASSERT(this->IsShutNode());
336 morkBeadProbeMap::morkBeadProbeMap(morkEnv
* ev
, const morkUsage
& inUsage
,
337 nsIMdbHeap
* ioHeap
, nsIMdbHeap
* ioSlotHeap
)
338 : morkProbeMap(ev
, inUsage
, ioHeap
,
339 /*inKeySize*/ sizeof(morkBead
*), /*inValSize*/ 0,
340 ioSlotHeap
, /*startSlotCount*/ 11,
341 /*inZeroIsClearKey*/ morkBool_kTrue
)
344 mNode_Derived
= morkDerived_kBeadProbeMap
;
347 /*public non-poly*/ void
348 morkBeadProbeMap::CloseBeadProbeMap(morkEnv
* ev
) // called by CloseMorkNode();
352 if ( this->IsNode() )
354 this->CutAllBeads(ev
);
355 this->CloseProbeMap(ev
);
359 this->NonNodeError(ev
);
362 ev
->NilPointerError();
365 // } ===== end morkNode methods =====
366 // ````` ````` ````` ````` `````
368 /*virtual*/ mork_test
// hit(a,b) implies hash(a) == hash(b)
369 morkBeadProbeMap::MapTest(morkEnv
* ev
, const void* inMapKey
,
370 const void* inAppKey
) const
373 const morkBead
* key
= *(const morkBead
**) inMapKey
;
376 mork_bool hit
= key
->BeadEqual(*(const morkBead
**) inAppKey
);
377 return ( hit
) ? morkTest_kHit
: morkTest_kMiss
;
380 return morkTest_kVoid
;
383 /*virtual*/ mork_u4
// hit(a,b) implies hash(a) == hash(b)
384 morkBeadProbeMap::MapHash(morkEnv
* ev
, const void* inAppKey
) const
386 const morkBead
* key
= *(const morkBead
**) inAppKey
;
388 return key
->BeadHash();
391 ev
->NilPointerWarning();
397 morkBeadProbeMap::ProbeMapHashMapKey(morkEnv
* ev
,
398 const void* inMapKey
) const
400 const morkBead
* key
= *(const morkBead
**) inMapKey
;
402 return key
->BeadHash();
405 ev
->NilPointerWarning();
411 morkBeadProbeMap::AddBead(morkEnv
* ev
, morkBead
* ioBead
)
413 if ( ioBead
&& ev
->Good() )
415 morkBead
* bead
= 0; // old key in the map
417 mork_bool put
= this->MapAtPut(ev
, &ioBead
, /*val*/ (void*) 0,
418 /*key*/ &bead
, /*val*/ (void*) 0);
420 if ( put
) // replaced an existing key?
422 if ( bead
!= ioBead
) // new bead was not already in table?
423 ioBead
->AddStrongRef(ev
); // now there's another ref
425 if ( bead
&& bead
!= ioBead
) // need to release old node?
426 bead
->CutStrongRef(ev
);
429 ioBead
->AddStrongRef(ev
); // now there's another ref
432 ev
->NilPointerError();
438 morkBeadProbeMap::GetBead(morkEnv
* ev
, mork_color inColor
)
440 morkBead
* oldBead
= 0; // old key in the map
441 morkBead
bead(inColor
);
442 morkBead
* key
= &bead
;
444 this->MapAt(ev
, &key
, &oldBead
, /*val*/ (void*) 0);
451 morkBeadProbeMap::CutAllBeads(morkEnv
* ev
)
452 // CutAllBeads() releases all the referenced bead values.
454 mork_num outSlots
= sMap_Slots
;
456 morkBeadProbeMapIter
i(ev
, this);
457 morkBead
* b
= i
.FirstBead(ev
);
470 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789