diff options
Diffstat (limited to 'db/mork/src/morkBead.cpp')
-rw-r--r-- | db/mork/src/morkBead.cpp | 425 |
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 + + |