gwnavruntime/kernel/SF_StringHash.h Source File

SF_StringHash.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 PublicHeader: None
10 Filename : KY_StringHash.h
11 Content : String hash table used when optional case-insensitive
12  lookup is required.
13 Created :
14 Authors :
15 
16 **************************************************************************/
17 
18 #ifndef INC_KY_Kernel_StringHash_H
19 #define INC_KY_Kernel_StringHash_H
20 
23 
24 namespace Kaim {
25 
26 // *** StringHash
27 
28 // This is a custom string hash table that supports case-insensitive
29 // searches through special functions such as GetCaseInsensitive, etc.
30 // This class is used for Flash labels, exports and other case-insensitive tables.
31 
32 template<class U, class Allocator = AllocatorGH<U> >
33 class StringHash : public Hash<String, U, String::NoCaseHashFunctor, Allocator>
34 {
35 public:
36  typedef U ValueType;
37  typedef StringHash<U, Allocator> SelfType;
38  typedef Hash<String, U, String::NoCaseHashFunctor, Allocator> BaseType;
39 
40 public:
41 
42  void operator = (const SelfType& src) { BaseType::operator = (src); }
43 
44  bool GetCaseInsensitive(const String& key, U* pvalue) const
45  {
46  String::NoCaseKey ikey(key);
47  return BaseType::GetAlt(ikey, pvalue);
48  }
49  // Pointer-returning get variety.
50  const U* GetCaseInsensitive(const String& key) const
51  {
52  String::NoCaseKey ikey(key);
53  return BaseType::GetAlt(ikey);
54  }
55  U* GetCaseInsensitive(const String& key)
56  {
57  String::NoCaseKey ikey(key);
58  return BaseType::GetAlt(ikey);
59  }
60 
61 
62  typedef typename BaseType::Iterator base_iterator;
63 
64  base_iterator FindCaseInsensitive(const String& key)
65  {
66  String::NoCaseKey ikey(key);
67  return BaseType::FindAlt(ikey);
68  }
69 
70  // Set just uses a find and assigns value if found. The key is not modified;
71  // this behavior is identical to Flash string variable assignment.
72  void SetCaseInsensitive(const String& key, const U& value)
73  {
74  base_iterator it = FindCaseInsensitive(key);
75  if (it != BaseType::End())
76  {
77  it->Second = value;
78  }
79  else
80  {
81  BaseType::Add(key, value);
82  }
83  }
84 };
85 
86 
87 // Global version that assigns the id.
88 template<class U, int SID = Stat_Default_Mem>
89 class StringHash_sid : public StringHash<U, AllocatorGH<U, SID> >
90 {
91  typedef StringHash_sid<U, SID> SelfType;
92  typedef StringHash<U, AllocatorGH<U, SID> > BaseType;
93 public:
94 
95  void operator = (const SelfType& src) { BaseType::operator = (src); }
96 };
97 
98 
99 
100 
101 // ***** StringHashLH: Structure heap local String Hash table
102 
103 // This hash table must live locally within a heap-allocated structure
104 // and is also allocates its string from the local heap by using StringLcl.
105 //
106 // This hash table needs to have custom implementation, since all strings
107 // are passed by String reference, so the locally stored value is not the same.
108 
109 
110 template<class U, class HashF>
111 struct StringLH_HashNode
112 {
113  StringLH First;
114  U Second;
115 
116  // NodeRef is used to allow passing of elements into ghash_set
117  // without using a temporary object.
118  struct NodeRef
119  {
120  const String* pFirst;
121  const U* pSecond;
122 
123  NodeRef(const String& f, const U& s) : pFirst(&f), pSecond(&s) { }
124  NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { }
125 
126  // Enable computation of ghash_node_hashf.
127  inline UPInt GetHash() const { return HashF()(*pFirst); }
128  // Necessary conversion to allow ghash_node::operator == to work.
129  operator const String& () const { return *pFirst; }
130  };
131 
132  // Note: No default constructor is necessary.
133  StringLH_HashNode(const StringLH_HashNode& src) : First(src.First), Second(src.Second) { }
134  StringLH_HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) { }
135  void operator = (const NodeRef& src) { First = *src.pFirst; Second = *src.pSecond; }
136 
137 
138  template<class K>
139  bool operator == (const K& src) const { return (First == src); }
140 
141  template<class K>
142  static UPInt CalcHash(const K& data) { return HashF()(data); }
143  inline UPInt GetHash() const { return HashF()(First); }
144 
145  // Hash functors used with this node. A separate functor is used for alternative
146  // key lookup so that it does not need to access the '.First' element.
147  struct NodeHashF
148  {
149  template<class K>
150  UPInt operator()(const K& data) const { return data.GetHash(); }
151  };
152  struct NodeAltHashF
153  {
154  template<class K>
155  UPInt operator()(const K& data) const { return StringLH_HashNode<U,HashF>::CalcHash(data); }
156  };
157 };
158 
159 
160 #undef new
161 
162 template<class U, int SID = Stat_Default_Mem,
163  class HashF = String::NoCaseHashFunctor,
164  class HashNode = StringLH_HashNode<U,HashF>,
165  class Entry = HashsetCachedNodeEntry<HashNode, typename HashNode::NodeHashF> >
166 class StringHashLH
167 {
168 public:
169  KY_MEMORY_REDEFINE_NEW(StringHashLH, SID)
170 
171  typedef AllocatorLH<U, SID> Allocator;
172 
173  // Types used for hash_set.
174  typedef U ValueType;
175  typedef StringHashLH<U, SID, HashF, HashNode, Entry> SelfType;
176  typedef typename HashNode::NodeHashF HashNodeF;
177  typedef HashSet<HashNode, HashNodeF,
178  typename HashNode::NodeAltHashF,
179  Allocator, Entry > Container;
180 
181  // Actual hash table itself, implemented as hash_set.
182  Container mHash;
183 
184 public:
185 
186  StringHashLH() { }
187  StringHashLH(int sizeHint) : mHash(sizeHint) { }
188  StringHashLH(const SelfType& src) : mHash(src.mHash) { }
189  ~StringHashLH() { }
190 
191  void operator = (const SelfType& src) { mHash = src.mHash; }
192 
193  // Remove all entries from the Hash table.
194  inline void Clear() { mHash.Clear(); }
195  // Returns true if the mHash is empty.
196  inline bool IsEmpty() const { return mHash.IsEmpty(); }
197 
198  // Access (set).
199  inline void Set(const String& key, const U& value)
200  {
201  typename HashNode::NodeRef e(key, value);
202  mHash.Set(e);
203  }
204  inline void Add(const String& key, const U& value)
205  {
206  typename HashNode::NodeRef e(key, value);
207  mHash.Add(e);
208  }
209 
210  // Removes an element by clearing its Entry.
211  inline void Remove(const String& key)
212  {
213  mHash.RemoveAlt(key);
214  }
215  template<class K>
216  inline void RemoveAlt(const K& key)
217  {
218  mHash.RemoveAlt(key);
219  }
220 
221  // Retrieve the value under the given key.
222  // - If there's no value under the key, then return false and leave *pvalue alone.
223  // - If there is a value, return true, and set *Pvalue to the Entry's value.
224  // - If value == NULL, return true or false according to the presence of the key.
225  bool Get(const String& key, U* pvalue) const
226  {
227  const HashNode* p = mHash.GetAlt(key);
228  if (p)
229  {
230  if (pvalue)
231  *pvalue = p->Second;
232  return true;
233  }
234  return false;
235  }
236 
237  template<class K>
238  bool GetAlt(const K& key, U* pvalue) const
239  {
240  const HashNode* p = mHash.GetAlt(key);
241  if (p)
242  {
243  if (pvalue)
244  *pvalue = p->Second;
245  return true;
246  }
247  return false;
248  }
249 
250  // Retrieve the pointer to a value under the given key.
251  // - If there's no value under the key, then return NULL.
252  // - If there is a value, return the pointer.
253  inline U* Get(const String& key)
254  {
255  HashNode* p = mHash.GetAlt(key);
256  return p ? &p->Second : 0;
257  }
258  inline const U* Get(const String& key) const
259  {
260  const HashNode* p = mHash.GetAlt(key);
261  return p ? &p->Second : 0;
262  }
263 
264  template<class K>
265  inline U* GetAlt(const K& key)
266  {
267  HashNode* p = mHash.GetAlt(key);
268  return p ? &p->Second : 0;
269  }
270  template<class K>
271  inline const U* GetAlt(const K& key) const
272  {
273  const HashNode* p = mHash.GetAlt(key);
274  return p ? &p->Second : 0;
275  }
276 
277  // Sizing methods - delegate to Hash.
278  inline UPInt GetSize() const { return mHash.GetSize(); }
279  inline void Resize(UPInt n) { mHash.Resize(n); }
280  inline void SetSapacity(UPInt newSize) { mHash.RemoveAlt(newSize); }
281 
282  // Iterator API, like STL.
283  typedef typename Container::ConstIterator ConstIterator;
284  typedef typename Container::Iterator Iterator;
285 
286  inline Iterator Begin() { return mHash.Begin(); }
287  inline Iterator End() { return mHash.End(); }
288  inline ConstIterator Begin() const { return mHash.Begin(); }
289  inline ConstIterator End() const { return mHash.End(); }
290 
291  Iterator Find(const String& key) { return mHash.FindAlt(key); }
292  ConstIterator Find(const String& key) const { return mHash.FindAlt(key); }
293 
294  template<class K>
295  Iterator FindAlt(const K& key) { return mHash.FindAlt(key); }
296  template<class K>
297  ConstIterator FindAlt(const K& key) const { return mHash.FindAlt(key); }
298 
299 
300  // **** Case-Insensitive Lookup
301 
302  bool GetCaseInsensitive(const String& key, U* pvalue) const
303  {
304  String::NoCaseKey ikey(key);
305  return GetAlt(ikey, pvalue);
306  }
307  // Pointer-returning get variety.
308  const U* GetCaseInsensitive(const String& key) const
309  {
310  String::NoCaseKey ikey(key);
311  return GetAlt(ikey);
312  }
313  U* GetCaseInsensitive(const String& key)
314  {
315  String::NoCaseKey ikey(key);
316  return GetAlt(ikey);
317  }
318 
319 
320  // typedef typename BaseType::Iterator base_iterator;
321 
322  Iterator FindCaseInsensitive(const String& key)
323  {
324  String::NoCaseKey ikey(key);
325  return FindAlt(ikey);
326  }
327 
328  // Set just uses a find and assigns value if found. The key is not modified;
329  // this behavior is identical to Flash string variable assignment.
330  void SetCaseInsensitive(const String& key, const U& value)
331  {
332  Iterator it = FindCaseInsensitive(key);
333  if (it != End())
334  {
335  it->Second = value;
336  }
337  else
338  {
339  Add(key, value);
340  }
341  }
342 
343 };
344 
345 } // Scaleform
346 
347 // Redefine operator 'new' if necessary.
348 #if defined(KY_DEFINE_NEW)
349 #define new KY_DEFINE_NEW
350 #endif
351 
352 #endif
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17