jhash.ipp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JHASH_IPP
  14. #define JHASH_IPP
  15. #include "platform.h"
  16. #include "jiface.hpp"
  17. #include "jobserve.ipp"
  18. #ifdef _WIN32
  19. #pragma warning( push )
  20. #pragma warning( disable : 4275 )
  21. #endif
  22. //NOTE on keysizes for hash tables
  23. //>0 - fixed size key
  24. //=0 - zero terminated key
  25. //<0 - fixed size followed by zero terminated key
  26. class jlib_decl MappingKey
  27. {
  28. public:
  29. MappingKey(const void * key, int keysize);
  30. ~MappingKey() { free(key); }
  31. private:
  32. MappingKey(void);
  33. public: // Not being too pernickety
  34. void *key; /* points to the key for this element */
  35. };
  36. class jlib_decl MappingBase : public CInterfaceOf<IMapping>
  37. {
  38. public:
  39. virtual unsigned getHash() const;
  40. virtual void setHash(unsigned);
  41. protected:
  42. //Packs into the remainder of the 8byte value from CInterface in 64bit
  43. unsigned hash;
  44. };
  45. class jlib_decl Mapping : extends MappingBase
  46. {
  47. public:
  48. Mapping(const void * k, int keysize) : key(k, keysize) {}
  49. virtual const void * getKey() const;
  50. private:
  51. MappingKey key;
  52. };
  53. class jlib_decl AtomBase : public CInterfaceOf<IAtom>
  54. {
  55. public:
  56. AtomBase(const void * k) : hash(0)
  57. {
  58. key = strdup((const char *)k);
  59. }
  60. ~AtomBase() { free(key); }
  61. //interface:IMapping
  62. virtual const char * queryStr() const { return key; }
  63. virtual const void * getKey() const;
  64. virtual unsigned getHash() const;
  65. virtual void setHash(unsigned);
  66. protected:
  67. unsigned hash;
  68. char * key;
  69. };
  70. class jlib_decl Atom : public AtomBase
  71. {
  72. public:
  73. Atom(const void * k) : AtomBase(k) {}
  74. };
  75. class jlib_decl ObservedAtom : public AtomBase
  76. {
  77. public:
  78. ObservedAtom(const void * k) : AtomBase(k) {}
  79. IMPLEMENT_IOBSERVABLE(AtomBase, observer)
  80. protected:
  81. SingleObserver observer;
  82. };
  83. class jlib_decl LowerCaseAtom : public Atom
  84. {
  85. public:
  86. LowerCaseAtom(const void * k) : Atom(k)
  87. {
  88. for (byte * cur = (byte *)key; *cur; cur++)
  89. *cur = (byte)tolower(*cur);
  90. }
  91. };
  92. class jlib_decl CaseAtom : public CInterfaceOf<IIdAtom>
  93. {
  94. public:
  95. CaseAtom(const void * k);
  96. ~CaseAtom() { free(text); }
  97. //interface:IMapping
  98. virtual const char * queryStr() const { return text; }
  99. virtual const void * getKey() const { return text; }
  100. virtual unsigned getHash() const { return hash; }
  101. virtual void setHash(unsigned _hash) { hash = _hash; }
  102. virtual IAtom * queryLower() const { return lower; }
  103. protected:
  104. unsigned hash;
  105. char * text;
  106. IAtom * lower;
  107. };
  108. template <class KEY, class KEYPARM>
  109. class MappingOf : extends MappingBase
  110. {
  111. public:
  112. MappingOf(KEYPARM k) : key(k) { };
  113. virtual const void * getKey() const { return &key; };
  114. private:
  115. KEY key;
  116. };
  117. template <class KEY, class KEYINIT, class VALUE_T, class VALINIT>
  118. class MappingBetween : extends MappingOf<KEY,KEYINIT>
  119. {
  120. public:
  121. MappingBetween(KEYINIT k, VALINIT a) :
  122. MappingOf<KEY,KEYINIT>(k), val(a) { };
  123. inline VALUE_T & getValue() { return val; };
  124. protected:
  125. VALUE_T val;
  126. };
  127. template <class VALUE_T,class VALINIT>
  128. class MappingStringTo : extends Atom
  129. {
  130. public:
  131. MappingStringTo(const char *k, VALINIT a) : Atom(k), val(a)
  132. { };
  133. inline VALUE_T & getValue() { return val; };
  134. protected:
  135. VALUE_T val;
  136. };
  137. template <class VALUE_T,class VALINIT>
  138. class MappingConstStringTo : public CInterfaceOf<IAtom>
  139. {
  140. public:
  141. MappingConstStringTo(const char *k, VALINIT a) : key(k), val(a), hash(0)
  142. { };
  143. inline VALUE_T & getValue() { return val; };
  144. //interface:IMapping
  145. virtual const char * queryStr() const { return key; }
  146. virtual const void * getKey() const { return key; }
  147. virtual unsigned getHash() const { return hash; }
  148. virtual void setHash(unsigned hval) { hash = hval; }
  149. protected:
  150. unsigned hash;
  151. const char * key;
  152. VALUE_T val;
  153. };
  154. template <class T, unsigned int K> class KeptHashTableOf
  155. : public KeptHashTable
  156. {
  157. public:
  158. inline KeptHashTableOf<T,K>(bool _ignorecase) : KeptHashTable(K, _ignorecase) {};
  159. inline T *create(const void *key) { return (T *) KeptHashTable::create(key); }
  160. inline T *createLink(const void *key) { return (T *) KeptHashTable::createLink(key); }
  161. inline T *find(const void *key) const { return (T *) KeptHashTable::find(key); }
  162. inline T *findLink(const void *key) const { return (T *) KeptHashTable::findLink(key); }
  163. inline T *next(const IMapping *i) const { return (T *) KeptHashTable::next(i); }
  164. protected:
  165. virtual IMapping *newMapping(const void * k) { return new T(k); }
  166. };
  167. class jlib_decl KeptAtomTable : public KeptHashTableOf<Atom, 0U>
  168. {
  169. public:
  170. KeptAtomTable() : KeptHashTableOf<Atom, 0U>(false) {};
  171. KeptAtomTable(bool _ignorecase) : KeptHashTableOf<Atom, 0U>(_ignorecase) {};
  172. inline IAtom * addAtom(const char *name)
  173. {
  174. return (IAtom *) create(name);
  175. };
  176. };
  177. class jlib_decl KeptLowerCaseAtomTable : public KeptHashTableOf<LowerCaseAtom, 0U>
  178. {
  179. public:
  180. KeptLowerCaseAtomTable() : KeptHashTableOf<LowerCaseAtom, 0U>(true) {};
  181. inline IAtom * addAtom(const char *name)
  182. {
  183. return (IAtom *) create(name);
  184. };
  185. };
  186. class jlib_decl KeptCaseAtomTable : public KeptHashTableOf<CaseAtom, 0U>
  187. {
  188. public:
  189. KeptCaseAtomTable() : KeptHashTableOf<CaseAtom, 0U>(false) {};
  190. virtual unsigned getTableLimit(unsigned max)
  191. {
  192. return max/2;
  193. }
  194. inline IIdAtom * addAtom(const char *name)
  195. {
  196. return create(name);
  197. };
  198. };
  199. template <class KEY>
  200. class HashKeyOf : public MappingBase
  201. {
  202. public:
  203. virtual const void * getKey() const { return &key; }
  204. protected:
  205. KEY key;
  206. };
  207. template <class KEY, class MAPPING>
  208. class MapOf : extends KeptHashTable
  209. {
  210. private:
  211. bool remove(MAPPING * mem);
  212. public:
  213. MapOf() : KeptHashTable(sizeof(KEY), false) {}
  214. MapOf(unsigned initsize) : KeptHashTable(initsize, sizeof(KEY), false) {}
  215. ~MapOf() {}
  216. inline bool add(MAPPING &mem) { return KeptHashTable::add(mem); }
  217. inline bool remove(const KEY & key) { return KeptHashTable::remove(&key); }
  218. inline bool removeExact(MAPPING * mem) { return KeptHashTable::removeExact(mem); }
  219. inline MAPPING * find(const KEY & key) const { return (MAPPING *)KeptHashTable::find(&key); }
  220. inline MAPPING * findLink(const KEY & key) const { return (MAPPING *)KeptHashTable::findLink(&key); }
  221. };
  222. template <class MAPPING>
  223. class StringMapOf : extends KeptHashTable
  224. {
  225. private:
  226. bool remove(MAPPING * mem);
  227. public:
  228. StringMapOf(bool _ignorecase) : KeptHashTable(0, _ignorecase) {}
  229. StringMapOf(unsigned initsize, bool _ignorecase) : KeptHashTable(initsize, 0, _ignorecase) {}
  230. ~StringMapOf() {}
  231. inline bool add(MAPPING &mem) { return KeptHashTable::add(mem); }
  232. inline bool remove(const char *key) { return KeptHashTable::remove(key); }
  233. inline bool removeExact(MAPPING * mem) { return KeptHashTable::removeExact(mem); }
  234. inline MAPPING * find(const char *key) const { return (MAPPING *)KeptHashTable::find(key); }
  235. };
  236. template <class KEY, class KEYINIT, class VALUE_T, class VALINIT, class MAPPING = MappingBetween<KEY, KEYINIT, VALUE_T, VALINIT> >
  237. class MapBetween : extends MapOf<KEY, MAPPING>
  238. {
  239. typedef MapBetween<KEY, KEYINIT, VALUE_T, VALINIT, MAPPING> SELF;
  240. public:
  241. MapBetween():MapOf<KEY,MAPPING>(){};
  242. MapBetween(unsigned initsize):MapOf<KEY,MAPPING>(initsize){};
  243. VALUE_T * getValue(KEYINIT k) const
  244. {
  245. KEY temp(k);
  246. MAPPING * map = SELF::find(temp);
  247. if (map)
  248. return &map->getValue();
  249. return NULL;
  250. }
  251. static inline VALUE_T * mapToValue(IMapping * _map)
  252. {
  253. MAPPING * map = (MAPPING *)_map;
  254. return &map->getValue();
  255. }
  256. /* k, v: not linked. v will be linked once. */
  257. bool setValue(KEYINIT k, VALINIT v)
  258. {
  259. MAPPING * map = new MAPPING(k, v);
  260. return this->replaceOwn(*map);
  261. }
  262. };
  263. template <class VALUE_T, class VALINIT = VALUE_T, class MAPPING = MappingStringTo<VALUE_T, VALINIT> >
  264. class MapStringTo : extends StringMapOf<MAPPING>
  265. {
  266. typedef MapStringTo<VALUE_T, VALINIT, MAPPING> SELF;
  267. public:
  268. MapStringTo():StringMapOf<MAPPING>(false){};
  269. MapStringTo(unsigned initsize, bool _ignorecase):StringMapOf<MAPPING>(initsize, _ignorecase){};
  270. MapStringTo(bool _ignorecase):StringMapOf<MAPPING>(_ignorecase){};
  271. VALUE_T * getValue(const char *k) const
  272. {
  273. MAPPING * map = SELF::find(k);
  274. if (map)
  275. return &map->getValue();
  276. return NULL;
  277. }
  278. static inline VALUE_T * mapToValue(IMapping * _map)
  279. {
  280. MAPPING * map = (MAPPING *)_map;
  281. return &map->getValue();
  282. }
  283. bool setValue(const char *k, VALINIT v)
  284. {
  285. MAPPING * map = new MAPPING(k, v);
  286. return this->replaceOwn(*map);
  287. }
  288. };
  289. template <class VALUE_T, class VALINIT = VALUE_T, class MAPPING = MappingConstStringTo<VALUE_T, VALINIT> >
  290. class MapConstStringTo : extends StringMapOf<MAPPING>
  291. {
  292. typedef MapConstStringTo<VALUE_T, VALINIT, MAPPING> SELF;
  293. public:
  294. MapConstStringTo():StringMapOf<MAPPING>(false){};
  295. MapConstStringTo(unsigned initsize, bool _ignorecase):StringMapOf<MAPPING>(initsize, _ignorecase){};
  296. MapConstStringTo(bool _ignorecase):StringMapOf<MAPPING>(_ignorecase){};
  297. VALUE_T * getValue(const char *k) const
  298. {
  299. MAPPING * map = SELF::find(k);
  300. if (map)
  301. return &map->getValue();
  302. return NULL;
  303. }
  304. static inline VALUE_T * mapToValue(IMapping * _map)
  305. {
  306. MAPPING * map = (MAPPING *)_map;
  307. return &map->getValue();
  308. }
  309. bool setValue(const char *k, VALINIT v)
  310. {
  311. MAPPING * map = new MAPPING(k, v);
  312. return this->replaceOwn(*map);
  313. }
  314. };
  315. typedef const char * char_ptr;
  316. typedef MapStringTo<StringAttr, char_ptr> StringAttrMapping;
  317. #ifdef _WIN32
  318. #pragma warning( pop )
  319. #endif
  320. #endif