summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/mork/morkIntMap.h
blob: 97f9c4b97783e1d276539ffd29f26ed817e27db5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* -*- 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 _MORKINTMAP_
#define _MORKINTMAP_ 1

#ifndef _MORK_
#  include "mork.h"
#endif

#ifndef _MORKNODE_
#  include "morkNode.h"
#endif

#ifndef _MORKMAP_
#  include "morkMap.h"
#endif

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */

#define morkIntMap_kStartSlotCount 256

/*| morkIntMap: maps mork_token -> morkNode
|*/
class morkIntMap : public morkMap {  // for mapping tokens to maps

  // { ===== begin morkNode interface =====
 public:  // morkNode virtual methods
  virtual void CloseMorkNode(
      morkEnv* ev) override;  // CloseIntMap() only if open
  virtual ~morkIntMap();      // assert that CloseIntMap() executed earlier

 public:  // morkMap construction & destruction
  // keySize for morkIntMap equals sizeof(mork_u4)
  morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize,
             nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
             mork_bool inHoldChanges);
  void CloseIntMap(morkEnv* ev);  // called by CloseMorkNode();

 public:  // dynamic type identification
  mork_bool IsIntMap() const {
    return IsNode() && mNode_Derived == morkDerived_kIntMap;
  }
  // } ===== end morkNode methods =====

  // { ===== begin morkMap poly interface =====
  virtual mork_bool  // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
  Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const override;

  virtual mork_u4  // some integer function of *((mork_u4*) inKey)
  Hash(morkEnv* ev, const void* inKey) const override;
  // } ===== end morkMap poly interface =====

 public:  // other map methods
  mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
  // the AddInt() boolean return equals ev->Good().

  mork_bool CutInt(morkEnv* ev, mork_u4 inKey);
  // The CutInt() boolean return indicates whether removal happened.

  void* GetInt(morkEnv* ev, mork_u4 inKey);
  // Note the returned node does NOT have an increase in refcount for this.

  mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
  // Note the returned node does NOT have an increase in refcount for this.
};

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#ifdef MORK_POINTER_MAP_IMPL

#  define morkDerived_kPointerMap /*i*/ 0x704D /* ascii 'pM' */

#  define morkPointerMap_kStartSlotCount 256

/*| morkPointerMap: maps void* -> void*
**|
**| This pointer map class is equivalent to morkIntMap when sizeof(mork_u4)
**| equals sizeof(void*).  However, when these two sizes are different,
**| then we cannot use the same hash table structure very easily without
**| being very careful about the size and usage assumptions of those
**| clients using the smaller data type.  So we just go ahead and use
**| morkPointerMap for hash tables using pointer key types.
|*/
class morkPointerMap : public morkMap {  // for mapping tokens to maps

  // { ===== begin morkNode interface =====
 public:  // morkNode virtual methods
  virtual void CloseMorkNode(
      morkEnv* ev) override;  // ClosePointerMap() only if open
  virtual ~morkPointerMap();  // assert that ClosePointerMap() executed earlier

 public:  // morkMap construction & destruction
  // keySize for morkPointerMap equals sizeof(mork_u4)
  morkPointerMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
                 nsIMdbHeap* ioSlotHeap);
  void ClosePointerMap(morkEnv* ev);  // called by CloseMorkNode();

 public:  // dynamic type identification
  mork_bool IsPointerMap() const {
    return IsNode() && mNode_Derived == morkDerived_kPointerMap;
  }
  // } ===== end morkNode methods =====

  // { ===== begin morkMap poly interface =====
  virtual mork_bool  // *((void**) inKeyA) == *((void**) inKeyB)
  Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;

  virtual mork_u4  // some integer function of *((mork_u4*) inKey)
  Hash(morkEnv* ev, const void* inKey) const;
  // } ===== end morkMap poly interface =====

 public:  // other map methods
  mork_bool AddPointer(morkEnv* ev, void* inKey, void* ioAddress);
  // the AddPointer() boolean return equals ev->Good().

  mork_bool CutPointer(morkEnv* ev, void* inKey);
  // The CutPointer() boolean return indicates whether removal happened.

  void* GetPointer(morkEnv* ev, void* inKey);
  // Note the returned node does NOT have an increase in refcount for this.

  mork_bool HasPointer(morkEnv* ev, void* inKey);
  // Note the returned node does NOT have an increase in refcount for this.

 public:  // typesafe refcounting inlines calling inherited morkNode methods
  static void SlotWeakIntMap(morkIntMap* me, morkEnv* ev, morkIntMap** ioSlot) {
    morkNode::SlotWeakNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }

  static void SlotStrongIntMap(morkIntMap* me, morkEnv* ev,
                               morkIntMap** ioSlot) {
    morkNode::SlotStrongNode((morkNode*)me, ev, (morkNode**)ioSlot);
  }
};
#endif /*MORK_POINTER_MAP_IMPL*/

// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

#endif /* _MORKINTMAP_ */