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 _MORKBEAD_
7 #define _MORKBEAD_ 1
8 
9 #ifndef _MORK_
10 #  include "mork.h"
11 #endif
12 
13 #ifndef _MORKNODE_
14 #  include "morkNode.h"
15 #endif
16 
17 #ifndef _MORKMAP_
18 #  include "morkMap.h"
19 #endif
20 
21 #ifndef _MORKPROBEMAP_
22 #  include "morkProbeMap.h"
23 #endif
24 
25 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
26 
27 #define morkDerived_kBead /*i*/ 0x426F /* ascii 'Bo' */
28 
29 /*| morkBead: subclass of morkNode that adds knowledge of db suite factory
30 **| and containing port to those objects that are exposed as instances of
31 **| nsIMdbBead in the public interface.
32 |*/
33 class morkBead : public morkNode {
34   // public: // slots inherited from morkNode (meant to inform only)
35   // nsIMdbHeap*    mNode_Heap;
36 
37   // mork_base      mNode_Base;     // must equal morkBase_kNode
38   // mork_derived   mNode_Derived;  // depends on specific node subclass
39 
40   // mork_access    mNode_Access;   // kOpen, kClosing, kShut, or kDead
41   // mork_usage     mNode_Usage;    // kHeap, kStack, kMember, kGlobal, kNone
42   // mork_able      mNode_Mutable;  // can this node be modified?
43   // mork_load      mNode_Load;     // is this node clean or dirty?
44 
45   // mork_uses      mNode_Uses;     // refcount for strong refs
46   // mork_refs      mNode_Refs;     // refcount for strong refs + weak refs
47 
48  public:  // state is public because the entire Mork system is private
49   mork_color mBead_Color;  // ID for this bead
50 
51  public:  // Hash() and Equal() for bead maps are same for all subclasses:
BeadHash()52   mork_u4 BeadHash() const { return (mork_u4)mBead_Color; }
BeadEqual(const morkBead * inBead)53   mork_bool BeadEqual(const morkBead* inBead) const {
54     return (mBead_Color == inBead->mBead_Color);
55   }
56 
57   // { ===== begin morkNode interface =====
58  public:                                             // morkNode virtual methods
59   virtual void CloseMorkNode(morkEnv* ev) override;  // CloseBead() only if open
60   virtual ~morkBead();  // assert that CloseBead() executed earlier
61 
62  public:  // special case for stack construction for map usage:
63   explicit morkBead(mork_color inBeadColor);  // stack-based bead instance
64 
65  protected:  // special case for morkObject:
66   morkBead(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
67            mork_color inBeadColor);
68 
69  public:  // morkEnv construction & destruction
70   morkBead(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
71            mork_color inBeadColor);
72   void CloseBead(morkEnv* ev);  // called by CloseMorkNode();
73 
74  private:  // copying is not allowed
75   morkBead(const morkBead& other);
76   morkBead& operator=(const morkBead& other);
77 
78  public:  // dynamic type identification
IsBead()79   mork_bool IsBead() const {
80     return IsNode() && mNode_Derived == morkDerived_kBead;
81   }
82   // } ===== end morkNode methods =====
83 
84   // void NewNilHandleError(morkEnv* ev); // mBead_Handle is nil
85 
86  public:  // typesafe refcounting inlines calling inherited morkNode methods
SlotWeakBead(morkBead * me,morkEnv * ev,morkBead ** ioSlot)87   static void SlotWeakBead(morkBead* me, morkEnv* ev, morkBead** ioSlot) {
88     morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
89   }
90 
SlotStrongBead(morkBead * me,morkEnv * ev,morkBead ** ioSlot)91   static void SlotStrongBead(morkBead* me, morkEnv* ev, morkBead** ioSlot) {
92     morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
93   }
94 };
95 
96 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
97 
98 #define morkDerived_kBeadMap /*i*/ 0x744D /* ascii 'bM' */
99 
100 /*| morkBeadMap: maps bead -> bead (key only using mBead_Color)
101 |*/
102 class morkBeadMap : public morkMap {
103   // { ===== begin morkNode interface =====
104  public:  // morkNode virtual methods
105   virtual void CloseMorkNode(
106       morkEnv* ev) override;  // CloseBeadMap() only if open
107   virtual ~morkBeadMap();     // assert that CloseBeadMap() executed earlier
108 
109  public:  // morkMap construction & destruction
110   morkBeadMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
111               nsIMdbHeap* ioSlotHeap);
112   void CloseBeadMap(morkEnv* ev);  // called by CloseMorkNode();
113 
114  public:  // dynamic type identification
IsBeadMap()115   mork_bool IsBeadMap() const {
116     return IsNode() && mNode_Derived == morkDerived_kBeadMap;
117   }
118   // } ===== end morkNode methods =====
119 
120   // { ===== begin morkMap poly interface =====
121  public:
122   virtual mork_bool  // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
123   Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const override;
124 
125   virtual mork_u4  // some integer function of *((mork_u4*) inKey)
126   Hash(morkEnv* ev, const void* inKey) const override;
127   // } ===== end morkMap poly interface =====
128 
129  public:  // other map methods
130   mork_bool AddBead(morkEnv* ev, morkBead* ioBead);
131   // the AddBead() boolean return equals ev->Good().
132 
133   mork_bool CutBead(morkEnv* ev, mork_color inColor);
134   // The CutBead() boolean return indicates whether removal happened.
135 
136   morkBead* GetBead(morkEnv* ev, mork_color inColor);
137   // Note the returned bead does NOT have an increase in refcount for this.
138 
139   mork_num CutAllBeads(morkEnv* ev);
140   // CutAllBeads() releases all the referenced beads.
141 };
142 
143 class morkBeadMapIter : public morkMapIter {  // typesafe wrapper class
144 
145  public:
morkBeadMapIter(morkEnv * ev,morkBeadMap * ioMap)146   morkBeadMapIter(morkEnv* ev, morkBeadMap* ioMap) : morkMapIter(ev, ioMap) {}
147 
morkBeadMapIter()148   morkBeadMapIter() : morkMapIter() {}
InitBeadMapIter(morkEnv * ev,morkBeadMap * ioMap)149   void InitBeadMapIter(morkEnv* ev, morkBeadMap* ioMap) {
150     this->InitMapIter(ev, ioMap);
151   }
152 
153   morkBead* FirstBead(morkEnv* ev);
154   morkBead* NextBead(morkEnv* ev);
155   morkBead* HereBead(morkEnv* ev);
156   void CutHereBead(morkEnv* ev);
157 };
158 
159 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
160 
161 #define morkDerived_kBeadProbeMap /*i*/ 0x6D74 /* ascii 'mb' */
162 
163 /*| morkBeadProbeMap: maps bead -> bead (key only using mBead_Color)
164 |*/
165 class morkBeadProbeMap : public morkProbeMap {
166   // { ===== begin morkNode interface =====
167  public:  // morkNode virtual methods
168   virtual void CloseMorkNode(
169       morkEnv* ev) override;    // CloseBeadProbeMap() only if open
170   virtual ~morkBeadProbeMap();  // assert that CloseBeadProbeMap() executed
171                                 // earlier
172 
173  public:  // morkMap construction & destruction
174   morkBeadProbeMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
175                    nsIMdbHeap* ioSlotHeap);
176   void CloseBeadProbeMap(morkEnv* ev);  // called by CloseMorkNode();
177 
178  public:  // dynamic type identification
IsBeadProbeMap()179   mork_bool IsBeadProbeMap() const {
180     return IsNode() && mNode_Derived == morkDerived_kBeadProbeMap;
181   }
182   // } ===== end morkNode methods =====
183 
184   // { ===== begin morkProbeMap methods =====
185  public:
186   virtual mork_test  // hit(a,b) implies hash(a) == hash(b)
187   MapTest(morkEnv* ev, const void* inMapKey,
188           const void* inAppKey) const override;
189 
190   virtual mork_u4  // hit(a,b) implies hash(a) == hash(b)
191   MapHash(morkEnv* ev, const void* inAppKey) const override;
192 
193   virtual mork_u4 ProbeMapHashMapKey(morkEnv* ev,
194                                      const void* inMapKey) const override;
195 
196   // virtual mork_bool ProbeMapIsKeyNil(morkEnv* ev, void* ioMapKey);
197 
198   // virtual void ProbeMapClearKey(morkEnv* ev, // put 'nil' into all keys
199   // inside map
200   //   void* ioMapKey, mork_count inKeyCount); // array of keys inside map
201 
202   // virtual void ProbeMapPushIn(morkEnv* ev, // move (key,val) into the map
203   //   const void* inAppKey, const void* inAppVal, // (key,val) outside map
204   //   void* outMapKey, void* outMapVal);      // (key,val) inside map
205 
206   // virtual void ProbeMapPullOut(morkEnv* ev, // move (key,val) out from the
207   // map
208   //   const void* inMapKey, const void* inMapVal, // (key,val) inside map
209   //   void* outAppKey, void* outAppVal) const;    // (key,val) outside map
210   // } ===== end morkProbeMap methods =====
211 
212  public:  // other map methods
213   mork_bool AddBead(morkEnv* ev, morkBead* ioBead);
214   // the AddBead() boolean return equals ev->Good().
215 
216   morkBead* GetBead(morkEnv* ev, mork_color inColor);
217   // Note the returned bead does NOT have an increase in refcount for this.
218 
219   mork_num CutAllBeads(morkEnv* ev);
220   // CutAllBeads() releases all the referenced bead values.
221 };
222 
223 class morkBeadProbeMapIter
224     : public morkProbeMapIter {  // typesafe wrapper class
225 
226  public:
morkBeadProbeMapIter(morkEnv * ev,morkBeadProbeMap * ioMap)227   morkBeadProbeMapIter(morkEnv* ev, morkBeadProbeMap* ioMap)
228       : morkProbeMapIter(ev, ioMap) {}
229 
morkBeadProbeMapIter()230   morkBeadProbeMapIter() : morkProbeMapIter() {}
InitBeadProbeMapIter(morkEnv * ev,morkBeadProbeMap * ioMap)231   void InitBeadProbeMapIter(morkEnv* ev, morkBeadProbeMap* ioMap) {
232     this->InitProbeMapIter(ev, ioMap);
233   }
234 
FirstBead(morkEnv * ev)235   morkBead* FirstBead(morkEnv* ev) { return (morkBead*)this->IterFirstKey(ev); }
236 
NextBead(morkEnv * ev)237   morkBead* NextBead(morkEnv* ev) { return (morkBead*)this->IterNextKey(ev); }
238 
HereBead(morkEnv * ev)239   morkBead* HereBead(morkEnv* ev) { return (morkBead*)this->IterHereKey(ev); }
240 };
241 
242 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
243 
244 #endif /* _MORKBEAD_ */
245