DictionaryEntry.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace JsUtil
  7. {
  8. template <class TValue>
  9. class BaseValueEntry
  10. {
  11. protected:
  12. TValue value; // data of entry
  13. void Set(TValue const& value)
  14. {
  15. this->value = value;
  16. }
  17. public:
  18. int next; // Index of next entry, -1 if last
  19. static bool SupportsCleanup()
  20. {
  21. return false;
  22. }
  23. static bool NeedsCleanup(BaseValueEntry<TValue>&)
  24. {
  25. return false;
  26. }
  27. TValue const& Value() const { return value; }
  28. TValue& Value() { return value; }
  29. void SetValue(TValue const& value) { this->value = value; }
  30. };
  31. template <class TValue>
  32. class ValueEntry: public BaseValueEntry<TValue>
  33. {
  34. public:
  35. void Clear()
  36. {
  37. }
  38. };
  39. // Class specialization for pointer values to support clearing
  40. template <class TValue>
  41. class ValueEntry<TValue*>: public BaseValueEntry<TValue*>
  42. {
  43. public:
  44. void Clear()
  45. {
  46. this->value = nullptr;
  47. }
  48. };
  49. template <>
  50. class ValueEntry<bool>: public BaseValueEntry<bool>
  51. {
  52. public:
  53. void Clear()
  54. {
  55. this->value = false;
  56. }
  57. };
  58. template <>
  59. class ValueEntry<int>: public BaseValueEntry<int>
  60. {
  61. public:
  62. void Clear()
  63. {
  64. this->value = 0;
  65. }
  66. };
  67. template <>
  68. class ValueEntry<uint>: public BaseValueEntry<uint>
  69. {
  70. public:
  71. void Clear()
  72. {
  73. this->value = 0;
  74. }
  75. };
  76. template<class TKey, class TValue>
  77. struct ValueToKey
  78. {
  79. static TKey ToKey(const TValue &value) { return static_cast<TKey>(value); }
  80. };
  81. // Used by BaseHashSet, the default is that the key is the same as the value
  82. template <class TKey, class TValue>
  83. class ImplicitKeyValueEntry : public ValueEntry<TValue>
  84. {
  85. public:
  86. inline TKey Key() const { return ValueToKey<TKey, TValue>::ToKey(this->value); }
  87. void Set(TKey const& key, TValue const& value)
  88. {
  89. __super::Set(value);
  90. }
  91. };
  92. template <class TKey, class TValue>
  93. class BaseKeyValueEntry : public ValueEntry<TValue>
  94. {
  95. protected:
  96. TKey key; // key of entry
  97. void Set(TKey const& key, TValue const& value)
  98. {
  99. __super::Set(value);
  100. this->key = key;
  101. }
  102. public:
  103. TKey const& Key() const { return key; }
  104. };
  105. template <class TKey, class TValue>
  106. class KeyValueEntry : public BaseKeyValueEntry<TKey, TValue>
  107. {
  108. };
  109. template <class TKey, class TValue>
  110. class KeyValueEntry<TKey*, TValue> : public BaseKeyValueEntry<TKey*, TValue>
  111. {
  112. public:
  113. void Clear()
  114. {
  115. __super::Clear();
  116. this->key = nullptr;
  117. }
  118. };
  119. template <class TValue>
  120. class KeyValueEntry<int, TValue> : public BaseKeyValueEntry<int, TValue>
  121. {
  122. public:
  123. void Clear()
  124. {
  125. __super::Clear();
  126. this->key = 0;
  127. }
  128. };
  129. template <class TKey, class TValue, template <class K, class V> class THashEntry>
  130. class DefaultHashedEntry : public THashEntry<TKey, TValue>
  131. {
  132. public:
  133. template<typename Comparer, typename TLookup>
  134. inline bool KeyEquals(TLookup const& otherKey, hash_t otherHashCode)
  135. {
  136. return Comparer::Equals(this->Key(), otherKey);
  137. }
  138. template<typename Comparer>
  139. inline hash_t GetHashCode()
  140. {
  141. return ((Comparer::GetHashCode(this->Key()) & 0x7fffffff) << 1) | 1;
  142. }
  143. void Set(TKey const& key, TValue const& value, int hashCode)
  144. {
  145. __super::Set(key, value);
  146. }
  147. };
  148. template <class TKey, class TValue, template <class K, class V> class THashEntry>
  149. class CacheHashedEntry : public THashEntry<TKey, TValue>
  150. {
  151. hash_t hashCode; // Lower 31 bits of hash code << 1 | 1, 0 if unused
  152. public:
  153. static const int INVALID_HASH_VALUE = 0;
  154. template<typename Comparer, typename TLookup>
  155. inline bool KeyEquals(TLookup const& otherKey, hash_t otherHashCode)
  156. {
  157. Assert(TAGHASH(Comparer::GetHashCode(this->Key())) == this->hashCode);
  158. return this->hashCode == otherHashCode && Comparer::Equals(this->Key(), otherKey);
  159. }
  160. template<typename Comparer>
  161. inline hash_t GetHashCode()
  162. {
  163. Assert(TAGHASH(Comparer::GetHashCode(this->Key())) == this->hashCode);
  164. return hashCode;
  165. }
  166. void Set(TKey const& key, TValue const& value, hash_t hashCode)
  167. {
  168. __super::Set(key, value);
  169. this->hashCode = hashCode;
  170. }
  171. void Clear()
  172. {
  173. __super::Clear();
  174. this->hashCode = INVALID_HASH_VALUE;
  175. }
  176. };
  177. template <class TKey, class TValue>
  178. class SimpleHashedEntry : public DefaultHashedEntry<TKey, TValue, ImplicitKeyValueEntry> {};
  179. template <class TKey, class TValue>
  180. class HashedEntry : public CacheHashedEntry<TKey, TValue, ImplicitKeyValueEntry> {};
  181. template <class TKey, class TValue>
  182. class SimpleDictionaryEntry : public DefaultHashedEntry<TKey, TValue, KeyValueEntry> {};
  183. template <class TKey, class TValue>
  184. class DictionaryEntry: public CacheHashedEntry<TKey, TValue, KeyValueEntry> {};
  185. template <class TKey, class TValue>
  186. class WeakRefValueDictionaryEntry: public SimpleDictionaryEntry<TKey, TValue>
  187. {
  188. public:
  189. void Clear()
  190. {
  191. this->key = TKey();
  192. this->value = TValue();
  193. }
  194. static bool SupportsCleanup()
  195. {
  196. return true;
  197. }
  198. static bool NeedsCleanup(WeakRefValueDictionaryEntry<TKey, TValue> const& entry)
  199. {
  200. TValue weakReference = entry.Value();
  201. return (weakReference == nullptr || weakReference->Get() == nullptr);
  202. }
  203. };
  204. }