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 _MORKINTMAP_
7 #define _MORKINTMAP_ 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 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
22 
23 #define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
24 
25 #define morkIntMap_kStartSlotCount 256
26 
27 /*| morkIntMap: maps mork_token -> morkNode
28 |*/
29 class morkIntMap : public morkMap {  // for mapping tokens to maps
30 
31   // { ===== begin morkNode interface =====
32  public:  // morkNode virtual methods
33   virtual void CloseMorkNode(
34       morkEnv* ev) override;  // CloseIntMap() only if open
35   virtual ~morkIntMap();      // assert that CloseIntMap() executed earlier
36 
37  public:  // morkMap construction & destruction
38   // keySize for morkIntMap equals sizeof(mork_u4)
39   morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize,
40              nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
41              mork_bool inHoldChanges);
42   void CloseIntMap(morkEnv* ev);  // called by CloseMorkNode();
43 
44  public:  // dynamic type identification
IsIntMap()45   mork_bool IsIntMap() const {
46     return IsNode() && mNode_Derived == morkDerived_kIntMap;
47   }
48   // } ===== end morkNode methods =====
49 
50   // { ===== begin morkMap poly interface =====
51   virtual mork_bool  // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
52   Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const override;
53 
54   virtual mork_u4  // some integer function of *((mork_u4*) inKey)
55   Hash(morkEnv* ev, const void* inKey) const override;
56   // } ===== end morkMap poly interface =====
57 
58  public:  // other map methods
59   mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
60   // the AddInt() boolean return equals ev->Good().
61 
62   mork_bool CutInt(morkEnv* ev, mork_u4 inKey);
63   // The CutInt() boolean return indicates whether removal happened.
64 
65   void* GetInt(morkEnv* ev, mork_u4 inKey);
66   // Note the returned node does NOT have an increase in refcount for this.
67 
68   mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
69   // Note the returned node does NOT have an increase in refcount for this.
70 };
71 
72 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
73 
74 #ifdef MORK_POINTER_MAP_IMPL
75 
76 #  define morkDerived_kPointerMap /*i*/ 0x704D /* ascii 'pM' */
77 
78 #  define morkPointerMap_kStartSlotCount 256
79 
80 /*| morkPointerMap: maps void* -> void*
81 **|
82 **| This pointer map class is equivalent to morkIntMap when sizeof(mork_u4)
83 **| equals sizeof(void*).  However, when these two sizes are different,
84 **| then we cannot use the same hash table structure very easily without
85 **| being very careful about the size and usage assumptions of those
86 **| clients using the smaller data type.  So we just go ahead and use
87 **| morkPointerMap for hash tables using pointer key types.
88 |*/
89 class morkPointerMap : public morkMap {  // for mapping tokens to maps
90 
91   // { ===== begin morkNode interface =====
92  public:  // morkNode virtual methods
93   virtual void CloseMorkNode(
94       morkEnv* ev) override;  // ClosePointerMap() only if open
95   virtual ~morkPointerMap();  // assert that ClosePointerMap() executed earlier
96 
97  public:  // morkMap construction & destruction
98   // keySize for morkPointerMap equals sizeof(mork_u4)
99   morkPointerMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
100                  nsIMdbHeap* ioSlotHeap);
101   void ClosePointerMap(morkEnv* ev);  // called by CloseMorkNode();
102 
103  public:  // dynamic type identification
IsPointerMap()104   mork_bool IsPointerMap() const {
105     return IsNode() && mNode_Derived == morkDerived_kPointerMap;
106   }
107   // } ===== end morkNode methods =====
108 
109   // { ===== begin morkMap poly interface =====
110   virtual mork_bool  // *((void**) inKeyA) == *((void**) inKeyB)
111   Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
112 
113   virtual mork_u4  // some integer function of *((mork_u4*) inKey)
114   Hash(morkEnv* ev, const void* inKey) const;
115   // } ===== end morkMap poly interface =====
116 
117  public:  // other map methods
118   mork_bool AddPointer(morkEnv* ev, void* inKey, void* ioAddress);
119   // the AddPointer() boolean return equals ev->Good().
120 
121   mork_bool CutPointer(morkEnv* ev, void* inKey);
122   // The CutPointer() boolean return indicates whether removal happened.
123 
124   void* GetPointer(morkEnv* ev, void* inKey);
125   // Note the returned node does NOT have an increase in refcount for this.
126 
127   mork_bool HasPointer(morkEnv* ev, void* inKey);
128   // Note the returned node does NOT have an increase in refcount for this.
129 
130  public:  // typesafe refcounting inlines calling inherited morkNode methods
SlotWeakIntMap(morkIntMap * me,morkEnv * ev,morkIntMap ** ioSlot)131   static void SlotWeakIntMap(morkIntMap* me, morkEnv* ev, morkIntMap** ioSlot) {
132     morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
133   }
134 
SlotStrongIntMap(morkIntMap * me,morkEnv * ev,morkIntMap ** ioSlot)135   static void SlotStrongIntMap(morkIntMap* me, morkEnv* ev,
136                                morkIntMap** ioSlot) {
137     morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
138   }
139 };
140 #endif /*MORK_POINTER_MAP_IMPL*/
141 
142 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
143 
144 #endif /* _MORKINTMAP_ */
145