summaryrefslogtreecommitdiffstats
path: root/db/mork/src/morkBead.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'db/mork/src/morkBead.cpp')
-rw-r--r--db/mork/src/morkBead.cpp425
1 files changed, 425 insertions, 0 deletions
diff --git a/db/mork/src/morkBead.cpp b/db/mork/src/morkBead.cpp
new file mode 100644
index 000000000..2b552eff1
--- /dev/null
+++ b/db/mork/src/morkBead.cpp
@@ -0,0 +1,425 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _MDB_
+#include "mdb.h"
+#endif
+
+#ifndef _MORK_
+#include "mork.h"
+#endif
+
+#ifndef _MORKNODE_
+#include "morkNode.h"
+#endif
+
+#ifndef _MORKENV_
+#include "morkEnv.h"
+#endif
+
+#ifndef _MORKBEAD_
+#include "morkBead.h"
+#endif
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+// ````` ````` ````` ````` `````
+// { ===== begin morkNode interface =====
+
+/*public virtual*/ void
+morkBead::CloseMorkNode(morkEnv* ev) // CloseBead() only if open
+{
+ if ( this->IsOpenNode() )
+ {
+ this->MarkClosing();
+ this->CloseBead(ev);
+ this->MarkShut();
+ }
+}
+
+/*public virtual*/
+morkBead::~morkBead() // assert CloseBead() executed earlier
+{
+ MORK_ASSERT(mBead_Color==0 || mNode_Usage == morkUsage_kStack );
+}
+
+/*public non-poly*/
+morkBead::morkBead(mork_color inBeadColor)
+: morkNode( morkUsage_kStack )
+, mBead_Color( inBeadColor )
+{
+}
+
+/*public non-poly*/
+morkBead::morkBead(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
+ mork_color inBeadColor)
+: morkNode( inUsage, ioHeap )
+, mBead_Color( inBeadColor )
+{
+}
+
+/*public non-poly*/
+morkBead::morkBead(morkEnv* ev,
+ const morkUsage& inUsage, nsIMdbHeap* ioHeap, mork_color inBeadColor)
+: morkNode(ev, inUsage, ioHeap)
+, mBead_Color( inBeadColor )
+{
+ if ( ev->Good() )
+ {
+ if ( ev->Good() )
+ mNode_Derived = morkDerived_kBead;
+ }
+}
+
+/*public non-poly*/ void
+morkBead::CloseBead(morkEnv* ev) // called by CloseMorkNode();
+{
+ if ( this->IsNode() )
+ {
+ if ( !this->IsShutNode() )
+ {
+ mBead_Color = 0;
+ this->MarkShut();
+ }
+ }
+ else
+ this->NonNodeError(ev);
+}
+
+// } ===== end morkNode methods =====
+// ````` ````` ````` ````` `````
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+// ````` ````` ````` ````` `````
+// { ===== begin morkNode interface =====
+
+/*public virtual*/ void
+morkBeadMap::CloseMorkNode(morkEnv* ev) // CloseBeadMap() only if open
+{
+ if ( this->IsOpenNode() )
+ {
+ this->MarkClosing();
+ this->CloseBeadMap(ev);
+ this->MarkShut();
+ }
+}
+
+/*public virtual*/
+morkBeadMap::~morkBeadMap() // assert CloseBeadMap() executed earlier
+{
+ MORK_ASSERT(this->IsShutNode());
+}
+
+/*public non-poly*/
+morkBeadMap::morkBeadMap(morkEnv* ev,
+ const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
+: morkMap(ev, inUsage, ioHeap, sizeof(morkBead*), /*inValSize*/ 0,
+ /*slotCount*/ 11, ioSlotHeap, /*holdChanges*/ morkBool_kFalse)
+{
+ if ( ev->Good() )
+ mNode_Derived = morkDerived_kBeadMap;
+}
+
+/*public non-poly*/ void
+morkBeadMap::CloseBeadMap(morkEnv* ev) // called by CloseMorkNode();
+{
+ if ( this->IsNode() )
+ {
+ this->CutAllBeads(ev);
+ this->CloseMap(ev);
+ this->MarkShut();
+ }
+ else
+ this->NonNodeError(ev);
+}
+
+// } ===== end morkNode methods =====
+// ````` ````` ````` ````` `````
+
+mork_bool
+morkBeadMap::AddBead(morkEnv* ev, morkBead* ioBead)
+ // the AddBead() boolean return equals ev->Good().
+{
+ if ( ioBead && ev->Good() )
+ {
+ morkBead* oldBead = 0; // old key in the map
+
+ mork_bool put = this->Put(ev, &ioBead, /*val*/ (void*) 0,
+ /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0);
+
+ if ( put ) // replaced an existing key?
+ {
+ if ( oldBead != ioBead ) // new bead was not already in table?
+ ioBead->AddStrongRef(ev); // now there's another ref
+
+ if ( oldBead && oldBead != ioBead ) // need to release old node?
+ oldBead->CutStrongRef(ev);
+ }
+ else
+ ioBead->AddStrongRef(ev); // another ref if not already in table
+ }
+ else if ( !ioBead )
+ ev->NilPointerError();
+
+ return ev->Good();
+}
+
+mork_bool
+morkBeadMap::CutBead(morkEnv* ev, mork_color inColor)
+{
+ morkBead* oldBead = 0; // old key in the map
+ morkBead bead(inColor);
+ morkBead* key = &bead;
+
+ mork_bool outCutNode = this->Cut(ev, &key,
+ /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0);
+
+ if ( oldBead )
+ oldBead->CutStrongRef(ev);
+
+ bead.CloseBead(ev);
+ return outCutNode;
+}
+
+morkBead*
+morkBeadMap::GetBead(morkEnv* ev, mork_color inColor)
+ // Note the returned bead does NOT have an increase in refcount for this.
+{
+ morkBead* oldBead = 0; // old key in the map
+ morkBead bead(inColor);
+ morkBead* key = &bead;
+
+ this->Get(ev, &key, /*key*/ &oldBead, /*val*/ (void*) 0, (mork_change**) 0);
+
+ bead.CloseBead(ev);
+ return oldBead;
+}
+
+mork_num
+morkBeadMap::CutAllBeads(morkEnv* ev)
+ // CutAllBeads() releases all the referenced beads.
+{
+ mork_num outSlots = mMap_Slots;
+
+ morkBeadMapIter i(ev, this);
+ morkBead* b = i.FirstBead(ev);
+
+ while ( b )
+ {
+ b->CutStrongRef(ev);
+ i.CutHereBead(ev);
+ b = i.NextBead(ev);
+ }
+
+ return outSlots;
+}
+
+
+// { ===== begin morkMap poly interface =====
+/*virtual*/ mork_bool
+morkBeadMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
+{
+ MORK_USED_1(ev);
+ return (*(const morkBead**) inKeyA)->BeadEqual(
+ *(const morkBead**) inKeyB);
+}
+
+/*virtual*/ mork_u4
+morkBeadMap::Hash(morkEnv* ev, const void* inKey) const
+{
+ MORK_USED_1(ev);
+ return (*(const morkBead**) inKey)->BeadHash();
+}
+// } ===== end morkMap poly interface =====
+
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+
+morkBead* morkBeadMapIter::FirstBead(morkEnv* ev)
+{
+ morkBead* bead = 0;
+ this->First(ev, &bead, /*val*/ (void*) 0);
+ return bead;
+}
+
+morkBead* morkBeadMapIter::NextBead(morkEnv* ev)
+{
+ morkBead* bead = 0;
+ this->Next(ev, &bead, /*val*/ (void*) 0);
+ return bead;
+}
+
+morkBead* morkBeadMapIter::HereBead(morkEnv* ev)
+{
+ morkBead* bead = 0;
+ this->Here(ev, &bead, /*val*/ (void*) 0);
+ return bead;
+}
+
+void morkBeadMapIter::CutHereBead(morkEnv* ev)
+{
+ this->CutHere(ev, /*key*/ (void*) 0, /*val*/ (void*) 0);
+}
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+// ````` ````` ````` ````` `````
+// { ===== begin morkNode interface =====
+
+/*public virtual*/ void
+morkBeadProbeMap::CloseMorkNode(morkEnv* ev) // CloseBeadProbeMap() if open
+{
+ if ( this->IsOpenNode() )
+ {
+ this->MarkClosing();
+ this->CloseBeadProbeMap(ev);
+ this->MarkShut();
+ }
+}
+
+/*public virtual*/
+morkBeadProbeMap::~morkBeadProbeMap() // assert CloseBeadProbeMap() earlier
+{
+ MORK_ASSERT(this->IsShutNode());
+}
+
+
+/*public non-poly*/
+morkBeadProbeMap::morkBeadProbeMap(morkEnv* ev, const morkUsage& inUsage,
+ nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
+: morkProbeMap(ev, inUsage, ioHeap,
+ /*inKeySize*/ sizeof(morkBead*), /*inValSize*/ 0,
+ ioSlotHeap, /*startSlotCount*/ 11,
+ /*inZeroIsClearKey*/ morkBool_kTrue)
+{
+ if ( ev->Good() )
+ mNode_Derived = morkDerived_kBeadProbeMap;
+}
+
+/*public non-poly*/ void
+morkBeadProbeMap::CloseBeadProbeMap(morkEnv* ev) // called by CloseMorkNode();
+{
+ if ( this->IsNode() )
+ {
+ this->CutAllBeads(ev);
+ this->CloseProbeMap(ev);
+ this->MarkShut();
+ }
+ else
+ this->NonNodeError(ev);
+}
+
+// } ===== end morkNode methods =====
+// ````` ````` ````` ````` `````
+
+/*virtual*/ mork_test // hit(a,b) implies hash(a) == hash(b)
+morkBeadProbeMap::MapTest(morkEnv* ev, const void* inMapKey,
+ const void* inAppKey) const
+{
+ MORK_USED_1(ev);
+ const morkBead* key = *(const morkBead**) inMapKey;
+ if ( key )
+ {
+ mork_bool hit = key->BeadEqual(*(const morkBead**) inAppKey);
+ return ( hit ) ? morkTest_kHit : morkTest_kMiss;
+ }
+ else
+ return morkTest_kVoid;
+}
+
+/*virtual*/ mork_u4 // hit(a,b) implies hash(a) == hash(b)
+morkBeadProbeMap::MapHash(morkEnv* ev, const void* inAppKey) const
+{
+ const morkBead* key = *(const morkBead**) inAppKey;
+ if ( key )
+ return key->BeadHash();
+ else
+ {
+ ev->NilPointerWarning();
+ return 0;
+ }
+}
+
+/*virtual*/ mork_u4
+morkBeadProbeMap::ProbeMapHashMapKey(morkEnv* ev,
+ const void* inMapKey) const
+{
+ const morkBead* key = *(const morkBead**) inMapKey;
+ if ( key )
+ return key->BeadHash();
+ else
+ {
+ ev->NilPointerWarning();
+ return 0;
+ }
+}
+
+mork_bool
+morkBeadProbeMap::AddBead(morkEnv* ev, morkBead* ioBead)
+{
+ if ( ioBead && ev->Good() )
+ {
+ morkBead* bead = 0; // old key in the map
+
+ mork_bool put = this->MapAtPut(ev, &ioBead, /*val*/ (void*) 0,
+ /*key*/ &bead, /*val*/ (void*) 0);
+
+ if ( put ) // replaced an existing key?
+ {
+ if ( bead != ioBead ) // new bead was not already in table?
+ ioBead->AddStrongRef(ev); // now there's another ref
+
+ if ( bead && bead != ioBead ) // need to release old node?
+ bead->CutStrongRef(ev);
+ }
+ else
+ ioBead->AddStrongRef(ev); // now there's another ref
+ }
+ else if ( !ioBead )
+ ev->NilPointerError();
+
+ return ev->Good();
+}
+
+morkBead*
+morkBeadProbeMap::GetBead(morkEnv* ev, mork_color inColor)
+{
+ morkBead* oldBead = 0; // old key in the map
+ morkBead bead(inColor);
+ morkBead* key = &bead;
+
+ this->MapAt(ev, &key, &oldBead, /*val*/ (void*) 0);
+
+ bead.CloseBead(ev);
+ return oldBead;
+}
+
+mork_num
+morkBeadProbeMap::CutAllBeads(morkEnv* ev)
+ // CutAllBeads() releases all the referenced bead values.
+{
+ mork_num outSlots = sMap_Slots;
+
+ morkBeadProbeMapIter i(ev, this);
+ morkBead* b = i.FirstBead(ev);
+
+ while ( b )
+ {
+ b->CutStrongRef(ev);
+ b = i.NextBead(ev);
+ }
+ this->MapCutAll(ev);
+
+ return outSlots;
+}
+
+
+//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
+
+