diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/db/mork/morkBead.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mailnews/db/mork/morkBead.cpp')
-rw-r--r-- | comm/mailnews/db/mork/morkBead.cpp | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/comm/mailnews/db/mork/morkBead.cpp b/comm/mailnews/db/mork/morkBead.cpp new file mode 100644 index 0000000000..839322621f --- /dev/null +++ b/comm/mailnews/db/mork/morkBead.cpp @@ -0,0 +1,361 @@ +/* -*- 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 + +// 456789_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 ===== +// ````` ````` ````` ````` ````` + +// 456789_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 ===== + +// 456789_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); +} + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +// 456789_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; +} + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 |