SourceMod SDK  1.7
sm_stringhashmap.h
Go to the documentation of this file.
1 
32 #ifndef _include_sourcemod_hashtable_h_
33 #define _include_sourcemod_hashtable_h_
34 
47 #include <am-allocator-policies.h>
48 #include <am-hashmap.h>
49 #include <am-string.h>
50 #include <am-moveable.h>
51 #include <string.h>
52 
53 namespace SourceMod
54 {
55 
56 namespace detail
57 {
59  {
60  public:
61  CharsAndLength(const char *str)
62  : str_(str),
63  length_(0)
64  {
65  int c;
66  uint32_t hash = 0;
67  while ((c = *str++))
68  hash = c + (hash << 6) + (hash << 16) - hash;
69  hash_ = hash;
70  length_ = str - str_ - 1;
71  }
72 
73  uint32_t hash() const {
74  return hash_;
75  }
76  const char *chars() const {
77  return str_;
78  }
79  size_t length() const {
80  return length_;
81  }
82 
83  private:
84  const char *str_;
85  size_t length_;
86  uint32_t hash_;
87  };
88 
90  {
91  static inline bool matches(const CharsAndLength &lookup, const ke::AString &key) {
92  return lookup.length() == key.length() &&
93  memcmp(lookup.chars(), key.chars(), key.length()) == 0;
94  }
95  static inline uint32_t hash(const CharsAndLength &key) {
96  return key.hash();
97  }
98  };
99 }
100 
101 template <typename T>
103 {
105  typedef ke::HashMap<ke::AString, T, detail::StringHashMapPolicy> Internal;
106 
107 public:
108  StringHashMap()
109  : internal_(ke::SystemAllocatorPolicy()),
110  memory_used_(0)
111  {
112  if (!internal_.init())
113  internal_.reportOutOfMemory();
114  }
115 
116  typedef typename Internal::Result Result;
117  typedef typename Internal::Insert Insert;
118  typedef typename Internal::iterator iterator;
119 
120  // Some KTrie-like helper functions.
121  bool retrieve(const char *aKey, T *aResult = NULL)
122  {
123  CharsAndLength key(aKey);
124  Result r = internal_.find(key);
125  if (!r.found())
126  return false;
127  if (aResult)
128  *aResult = r->value;
129  return true;
130  }
131 
132  Result find(const char *aKey)
133  {
134  CharsAndLength key(aKey);
135  return internal_.find(key);
136  }
137 
138  bool contains(const char *aKey)
139  {
140  CharsAndLength key(aKey);
141  Result r = internal_.find(key);
142  return r.found();
143  }
144 
145  bool replace(const char *aKey, const T &value)
146  {
147  CharsAndLength key(aKey);
148  Insert i = internal_.findForAdd(key);
149  if (!i.found())
150  {
151  memory_used_ += key.length() + 1;
152  if (!internal_.add(i))
153  return false;
154  i->key = aKey;
155  }
156  i->value = value;
157  return true;
158  }
159 
160  bool insert(const char *aKey, const T &value)
161  {
162  CharsAndLength key(aKey);
163  Insert i = internal_.findForAdd(key);
164  if (i.found())
165  return false;
166  if (!internal_.add(i))
167  return false;
168  memory_used_ += key.length() + 1;
169  i->key = aKey;
170  i->value = value;
171  return true;
172  }
173 
174  bool remove(const char *aKey)
175  {
176  CharsAndLength key(aKey);
177  Result r = internal_.find(key);
178  if (!r.found())
179  return false;
180  memory_used_ -= key.length() + 1;
181  internal_.remove(r);
182  return true;
183  }
184 
185  void remove(Result &r)
186  {
187  internal_.remove(r);
188  }
189 
190  void clear()
191  {
192  internal_.clear();
193  }
194 
195  iterator iter()
196  {
197  return internal_.iter();
198  }
199 
200  size_t mem_usage() const
201  {
202  return internal_.estimateMemoryUse() + memory_used_;
203  }
204 
205  size_t elements() const
206  {
207  return internal_.elements();
208  }
209 
210 
211  Insert findForAdd(const char *aKey)
212  {
213  CharsAndLength key(aKey);
214  return internal_.findForAdd(key);
215  }
216 
217  // Note that |i->key| must be set after calling this, and the key must
218  // be the same as used with findForAdd(). It is best to avoid these two
219  // functions as the combined variants above are safer.
220  bool add(Insert &i)
221  {
222  return internal_.add(i);
223  }
224 
225  // Only value needs to be set after.
226  bool add(Insert &i, const char *aKey)
227  {
228  if (!internal_.add(i))
229  return false;
230  i->key = aKey;
231  return true;
232  }
233 
234 private:
235  Internal internal_;
236  size_t memory_used_;
237 };
238 
239 }
240 
241 #endif // _include_sourcemod_hashtable_h_
Definition: sm_stringhashmap.h:58
Definition: sm_stringhashmap.h:102
Definition: sm_stringhashmap.h:89
Definition: IAdminSystem.h:63