jsuperhash.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  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 SUPERHASH_HPP
  14. #define SUPERHASH_HPP
  15. //#define TRACE_HASH
  16. #undef expand
  17. #include "jiface.hpp"
  18. #include "jiter.hpp"
  19. #include "jstring.hpp"
  20. #include "jmutex.hpp"
  21. extern jlib_decl unsigned hashc( const unsigned char *k, unsigned length, unsigned initval);
  22. extern jlib_decl unsigned hashnc( const unsigned char *k, unsigned length, unsigned initval);
  23. class jlib_decl SuperHashTable : public CInterface
  24. {
  25. public:
  26. SuperHashTable(void);
  27. SuperHashTable(unsigned initsize);
  28. ~SuperHashTable();
  29. // Derived class destructor expected to call _releaseAll()
  30. void reinit(unsigned initsize);
  31. void kill(void);
  32. inline unsigned count() const { return tablecount; }
  33. inline unsigned ordinality() const { return tablecount; }
  34. inline memsize_t queryMem() const { return tablesize * sizeof(void *); } // hash table table memory size
  35. void * next(const void *et) const;
  36. void ensure(unsigned mincount);
  37. void releaseAll(); // like kill(), but does not resize the table
  38. void dumpStats() const;
  39. protected:
  40. void init(unsigned initsize);
  41. void _releaseAll(void); // not guaranteed to be thread safe, typically called from destructor
  42. inline bool add(void * et) { return doAdd(et, false); }
  43. inline bool replace(void * et) { return doAdd(et, true); }
  44. void addNew(void * et); //use this when you are sure the key does not already exist in the table (saves some needless matching)
  45. void addNew(void * donor, unsigned hash);
  46. void * addOrFind(void *);
  47. void * addOrFindExact(void * donor);
  48. inline void * find(const void * param) const { return table[doFind(param)]; }
  49. inline void * find(unsigned hashcode, const void * param) const { return table[doFind(hashcode, param)]; }
  50. void * findElement(unsigned hashcode, const void * searchE) const;
  51. void * findElement(const void * searchE) const;
  52. void * findExact(const void * et) const;
  53. // remove(void *) zaps key (i.e. a match using matchesFindParam method)
  54. // removeExact(void *) zaps element (i.e. a match using pointer==pointer)
  55. bool remove(const void * param);
  56. bool removeExact(void * et);
  57. inline void setCache(unsigned v) const { cache = v; }
  58. inline unsigned doFind(const void * findParam) const
  59. { return doFind(getHashFromFindParam(findParam), findParam); }
  60. unsigned firstIdx() const { return validIdx(0); }
  61. unsigned validIdx(unsigned i) const;
  62. private:
  63. bool doAdd(void *, bool);
  64. void doDeleteElement(unsigned);
  65. unsigned doFind(unsigned, const void *) const;
  66. unsigned doFindElement(unsigned, const void *) const;
  67. unsigned doFindNew(unsigned) const;
  68. unsigned doFindExact(const void *) const;
  69. void doKill(void);
  70. void expand();
  71. void expand(unsigned newsize);
  72. void note_searchlen(int) const;
  73. virtual void onAdd(void *et) = 0;
  74. virtual void onRemove(void *et) = 0;
  75. virtual unsigned getHashFromElement(const void *et) const = 0;
  76. virtual unsigned getHashFromFindParam(const void *fp) const = 0;
  77. virtual const void * getFindParam(const void *et) const = 0;
  78. virtual unsigned getTableLimit(unsigned max);
  79. virtual bool matchesFindParam(const void *et, const void *key, unsigned fphash) const = 0;
  80. virtual bool matchesElement(const void *et, const void *searchET) const;
  81. protected:
  82. mutable unsigned cache; // before pointer to improve 64bit packing.
  83. void * * table;
  84. unsigned tablesize;
  85. unsigned tablecount;
  86. #ifdef TRACE_HASH
  87. mutable int search_tot;
  88. mutable int search_num;
  89. mutable int search_max;
  90. #endif
  91. };
  92. template <class ET, class FP>
  93. class SuperHashTableOf : public SuperHashTable
  94. {
  95. public:
  96. typedef SuperHashTableOf<ET, FP> SELF;
  97. friend class ConstHashItem;
  98. class ConstHashItem
  99. {
  100. public:
  101. ConstHashItem(const SELF & _self, unsigned _idx) : self(_self), idx(_idx) {}
  102. ET & operator * () const { return self.element(idx); }
  103. bool operator != (const ConstHashItem & other) const { return &self != &other.self || idx != other.idx; }
  104. ConstHashItem & operator ++ () { idx = self.validIdx(idx+1); return *this; }
  105. private:
  106. const SELF & self;
  107. unsigned idx;
  108. };
  109. public:
  110. SuperHashTableOf(void) : SuperHashTable() {}
  111. SuperHashTableOf(unsigned initsize) : SuperHashTable(initsize) {}
  112. inline bool add(ET & et)
  113. { return SuperHashTable::add(&et); }
  114. inline bool replace(ET & et)
  115. { return SuperHashTable::replace(&et); }
  116. inline ET * addOrFind(ET & et)
  117. { return static_cast<ET *>(SuperHashTable::addOrFind(&et)); }
  118. inline ET * addOrFindExact(ET & et)
  119. { return static_cast<ET *>(SuperHashTable::addOrFindExact(&et)); }
  120. inline ET * find(const FP * fp) const
  121. { return static_cast<ET *>(SuperHashTable::find(fp)); }
  122. inline ET * next(const ET * et) const
  123. { return static_cast<ET *>(SuperHashTable::next(et)); }
  124. inline ET * find(unsigned hashCode, const FP * fp) const
  125. { return static_cast<ET *>(SuperHashTable::find(hashCode, fp)); }
  126. inline ET * findExact(const ET & et) const
  127. { return static_cast<ET *>(SuperHashTable::findExact(&et)); }
  128. inline bool remove(const FP * fp)
  129. { return SuperHashTable::remove((const void *)(fp)); }
  130. inline bool removeExact(ET * et)
  131. { return SuperHashTable::removeExact(et); }
  132. ConstHashItem begin() const { return ConstHashItem(*this, firstIdx()); }
  133. ConstHashItem end() const { return ConstHashItem(*this, SELF::tablesize); }
  134. private:
  135. ET & element(unsigned idx) const { return *static_cast<ET *>(this->table[idx]); }
  136. };
  137. // Macro to provide find method taking reference instead of pointer
  138. #define IMPLEMENT_SUPERHASHTABLEOF_REF_FIND(ET, FP) \
  139. inline ET * find(FP & fp) const \
  140. { return SuperHashTableOf<ET, FP>::find(&fp); }
  141. // simple type hashing HT impl.
  142. // elements (ET) must implement queryFindParam.
  143. template <class ET, class FP>
  144. class SimpleHashTableOf : public SuperHashTableOf<ET, FP>
  145. {
  146. typedef SimpleHashTableOf<ET, FP> SELF;
  147. public:
  148. SimpleHashTableOf<ET, FP>(void) : SuperHashTableOf<ET, FP>() { }
  149. SimpleHashTableOf<ET, FP>(unsigned initsize) : SuperHashTableOf<ET, FP>(initsize) { }
  150. ~SimpleHashTableOf<ET, FP>() { SELF::_releaseAll(); }
  151. IMPLEMENT_SUPERHASHTABLEOF_REF_FIND(ET, FP);
  152. virtual void onAdd(void * et __attribute__((unused))) { }
  153. virtual void onRemove(void * et __attribute__((unused))) { }
  154. virtual unsigned getHashFromElement(const void *et) const
  155. {
  156. return hashc((const unsigned char *) ((const ET *) et)->queryFindParam(), sizeof(FP), 0);
  157. }
  158. virtual unsigned getHashFromFindParam(const void *fp) const
  159. {
  160. return hashc((const unsigned char *) fp, sizeof(FP), 0);
  161. }
  162. virtual const void *getFindParam(const void *et) const
  163. {
  164. return ((const ET *)et)->queryFindParam();
  165. }
  166. virtual bool matchesFindParam(const void *et, const void *fp, unsigned fphash __attribute__((unused))) const
  167. {
  168. return *(FP *)((const ET *)et)->queryFindParam() == *(FP *)fp;
  169. }
  170. };
  171. template <class ET, class FP>
  172. class OwningSimpleHashTableOf : public SimpleHashTableOf<ET, FP>
  173. {
  174. typedef OwningSimpleHashTableOf<ET, FP> SELF;
  175. public:
  176. OwningSimpleHashTableOf<ET, FP>(void) : SimpleHashTableOf<ET, FP>() { }
  177. OwningSimpleHashTableOf<ET, FP>(unsigned initsize) : SimpleHashTableOf<ET, FP>(initsize) { }
  178. ~OwningSimpleHashTableOf<ET, FP>() { SELF::_releaseAll(); }
  179. virtual void onRemove(void *et) { ((ET *)et)->Release(); }
  180. };
  181. class jlib_decl SuperHashIterator : public CInterface
  182. {
  183. public:
  184. SuperHashIterator(const SuperHashTable & _table, bool _linkTable=true) : linkTable(_linkTable), table(_table) { cur = NULL; if (linkTable) table.Link(); }
  185. ~SuperHashIterator() { if (linkTable) table.Release(); }
  186. virtual bool first(void)
  187. { cur = table.next(NULL); return cur != NULL; }
  188. virtual bool isValid(void) { return cur != NULL; }
  189. virtual bool next(void)
  190. { if (cur) cur = table.next(cur); return (cur != NULL); }
  191. protected:
  192. void * queryPointer() { assertex(cur); return cur; }
  193. private:
  194. bool linkTable;
  195. const SuperHashTable & table;
  196. void * cur;
  197. };
  198. template <class ET>
  199. class SuperHashIteratorOf : public SuperHashIterator
  200. {
  201. public:
  202. SuperHashIteratorOf(const SuperHashTable & _table, bool linkTable=true) : SuperHashIterator(_table, linkTable) {}
  203. ET & query()
  204. { return *(static_cast<ET *>(queryPointer())); }
  205. };
  206. template <class ET, typename INTERFACE, bool LINKTABLE>
  207. class SuperHashIIteratorOf : public CInterfaceOf<INTERFACE>
  208. {
  209. public:
  210. SuperHashIIteratorOf(const SuperHashTable & _table) : table(_table) { cur = NULL; if (LINKTABLE) table.Link(); }
  211. ~SuperHashIIteratorOf() { if (LINKTABLE) table.Release(); }
  212. virtual bool first(void)
  213. {
  214. cur = table.next(NULL);
  215. return cur != NULL;
  216. }
  217. virtual bool isValid(void)
  218. {
  219. return cur != NULL;
  220. }
  221. virtual bool next(void)
  222. {
  223. if (cur) cur = table.next(cur);
  224. return (cur != NULL);
  225. }
  226. virtual ET & query()
  227. {
  228. assertex(cur);
  229. return *(static_cast<ET *>(cur));
  230. }
  231. virtual ET & get()
  232. {
  233. assertex(cur);
  234. return OLINK(*(static_cast<ET *>(cur)));
  235. }
  236. private:
  237. const SuperHashTable & table;
  238. void* cur;
  239. };
  240. template <class ET>
  241. class StringSuperHashTableOf : public SuperHashTableOf<ET, const char>
  242. {
  243. typedef StringSuperHashTableOf<ET> SELF;
  244. public:
  245. StringSuperHashTableOf<ET>(void) : SuperHashTableOf<ET, const char>() { }
  246. StringSuperHashTableOf<ET>(unsigned initsize) : SuperHashTableOf<ET, const char>(initsize) { }
  247. ~StringSuperHashTableOf<ET>() { SELF::_releaseAll(); }
  248. virtual void onAdd(void *et __attribute__((unused))) { }
  249. virtual void onRemove(void *et __attribute__((unused))) { }
  250. virtual unsigned getHashFromElement(const void *et) const
  251. {
  252. const char *str = ((const ET *) et)->queryFindString();
  253. return hashc((const unsigned char *) str, (size32_t)strlen(str), 0);
  254. }
  255. virtual unsigned getHashFromFindParam(const void *fp) const
  256. {
  257. return hashc((const unsigned char *) fp, (size32_t)strlen((const char *)fp), 0);
  258. }
  259. virtual const void *getFindParam(const void *et) const
  260. {
  261. return ((const ET *)et)->queryFindString();
  262. }
  263. virtual bool matchesFindParam(const void *et, const void *fp, unsigned fphash __attribute__((unused))) const
  264. {
  265. return (0==strcmp(((const ET *)et)->queryFindString(), (const char *)fp));
  266. }
  267. };
  268. template <class ET>
  269. class OwningStringSuperHashTableOf : public StringSuperHashTableOf<ET>
  270. {
  271. typedef OwningStringSuperHashTableOf<ET> SELF;
  272. public:
  273. OwningStringSuperHashTableOf<ET>(void) : StringSuperHashTableOf<ET>() { }
  274. OwningStringSuperHashTableOf<ET>(unsigned initsize) : StringSuperHashTableOf<ET>(initsize) { }
  275. ~OwningStringSuperHashTableOf<ET>() { SELF::_releaseAll(); }
  276. virtual void onRemove(void *et) { ((ET *)et)->Release(); }
  277. };
  278. // thread safe simple hash table impl.
  279. template <class ET, class FP>
  280. class ThreadSafeSimpleHashTableOf : private SuperHashTable
  281. {
  282. typedef ThreadSafeSimpleHashTableOf<ET, FP> SELF;
  283. virtual void onAdd(void *et __attribute__((unused))) { }
  284. virtual void onRemove(void *et __attribute__((unused))) { }
  285. virtual unsigned getHashFromElement(const void *et) const
  286. {
  287. return hashc((const unsigned char *) ((const ET *) et)->queryFindParam(), sizeof(FP), 0);
  288. }
  289. virtual unsigned getHashFromFindParam(const void *fp) const
  290. {
  291. return hashc((const unsigned char *) fp, sizeof(FP), 0);
  292. }
  293. virtual const void *getFindParam(const void *et) const
  294. {
  295. return ((const ET *)et)->queryFindParam();
  296. }
  297. virtual bool matchesFindParam(const void *et, const void *fp, unsigned fphash __attribute__((unused))) const
  298. {
  299. return *(FP *)((const ET *)et)->queryFindParam() == *(FP *)fp;
  300. }
  301. protected:
  302. using SuperHashTable::_releaseAll;
  303. public:
  304. mutable CriticalSection crit;
  305. ThreadSafeSimpleHashTableOf(void) : SuperHashTable() { }
  306. ThreadSafeSimpleHashTableOf(unsigned initsize) : SuperHashTable(initsize) { }
  307. ~ThreadSafeSimpleHashTableOf() { _releaseAll(); }
  308. ET *find(FP & fp) const
  309. {
  310. CriticalBlock block(crit);
  311. return (ET *) SuperHashTable::find(&fp);
  312. }
  313. SuperHashTable &queryBaseTable() { return *this; }
  314. void kill()
  315. {
  316. CriticalBlock block(crit);
  317. SuperHashTable::kill();
  318. }
  319. void releaseElements()
  320. {
  321. CriticalBlock block(crit);
  322. SuperHashTable::releaseAll();
  323. }
  324. bool add(ET & et)
  325. {
  326. CriticalBlock block(crit);
  327. return SuperHashTable::add(&et);
  328. }
  329. bool replace(ET & et)
  330. {
  331. CriticalBlock block(crit);
  332. return SuperHashTable::replace(&et);
  333. }
  334. ET * addOrFind(ET & et)
  335. {
  336. CriticalBlock block(crit);
  337. return static_cast<ET *>(SuperHashTable::addOrFind(&et));
  338. }
  339. ET * find(const FP * fp) const
  340. {
  341. CriticalBlock block(crit);
  342. return static_cast<ET *>(SuperHashTable::find(fp));
  343. }
  344. ET * findExact(const ET & et) const
  345. {
  346. CriticalBlock block(crit);
  347. return static_cast<ET *>(SuperHashTable::findExact(&et));
  348. }
  349. bool remove(const FP * fp)
  350. {
  351. CriticalBlock block(crit);
  352. return SuperHashTable::remove((const void *)(fp));
  353. }
  354. bool removeExact(ET * et)
  355. {
  356. CriticalBlock block(crit);
  357. return SuperHashTable::removeExact(et);
  358. }
  359. unsigned count() const
  360. {
  361. CriticalBlock block(crit);
  362. return SuperHashTable::count();
  363. }
  364. };
  365. template <class ET, class FP>
  366. class ThreadSafeOwningSimpleHashTableOf : public ThreadSafeSimpleHashTableOf<ET, FP>
  367. {
  368. typedef ThreadSafeOwningSimpleHashTableOf<ET, FP> SELF;
  369. public:
  370. ~ThreadSafeOwningSimpleHashTableOf<ET, FP>() { SELF::_releaseAll(); }
  371. virtual void onRemove(void *et) { ((ET *)et)->Release(); }
  372. };
  373. // template mapping object for base type to arbitrary object
  374. template <class ET, class FP>
  375. class HTMapping : public CInterface
  376. {
  377. protected:
  378. ET &et;
  379. FP fp;
  380. public:
  381. HTMapping(ET &_et, const FP &_fp) : et(_et), fp(_fp) { }
  382. const void *queryFindParam() const { return &fp; }
  383. ET &queryElement() const { return et; }
  384. FP &queryFindValue() const { return fp; }
  385. };
  386. // template mapping object for base type to IInterface object
  387. template <class ET, class FP>
  388. class OwningHTMapping : public HTMapping<ET, FP>
  389. {
  390. public:
  391. OwningHTMapping(ET &et, FP &fp) : HTMapping<ET, FP>(et, fp) { }
  392. ~OwningHTMapping() { this->et.Release(); }
  393. };
  394. template <class ET, class FP>
  395. class LinkedHTMapping : public OwningHTMapping<ET, FP>
  396. {
  397. public:
  398. LinkedHTMapping(ET &et, FP &fp) : OwningHTMapping<ET, FP>(et, fp) { this->et.Link(); }
  399. };
  400. // template mapping object for string to arbitrary object
  401. template <class ET>
  402. class StringHTMapping : public CInterface
  403. {
  404. public:
  405. StringHTMapping(const char *_fp, ET &_et) : fp(_fp), et(_et) { }
  406. const char *queryFindString() const { return fp; }
  407. protected:
  408. ET &et;
  409. StringAttr fp;
  410. };
  411. // template mapping object for string to IInterface object
  412. template <class ET>
  413. class OwningStringHTMapping : public StringHTMapping<ET>
  414. {
  415. public:
  416. OwningStringHTMapping(const char *fp, ET &et) : StringHTMapping<ET>(fp, et) { }
  417. ~OwningStringHTMapping() { this->et.Release(); }
  418. ET &query() { return this->et; }
  419. ET &get() { this->et.Link(); return this->et; }
  420. };
  421. // NB: only really here, because of circular include problems
  422. // utility atom class, holding hash,string and count
  423. class jlib_decl HashKeyElement
  424. {
  425. public:
  426. const char *get() { return (const char *)keyPtr(); }
  427. unsigned length() { return (size32_t)strlen((const char *)keyPtr()); }
  428. unsigned queryHash() const { return hashValue; }
  429. unsigned queryReferences() { return linkCount+1; } // 1 implicit
  430. private:
  431. const char *keyPtr() { return ((const char *)this)+sizeof(*this); }
  432. unsigned hashValue;
  433. unsigned linkCount;
  434. HashKeyElement();
  435. friend class AtomRefTable;
  436. };
  437. #ifdef _MSC_VER
  438. #pragma warning(disable : 4275 )
  439. #endif
  440. typedef const char constcharptr;
  441. class jlib_decl AtomRefTable : public SuperHashTableOf<HashKeyElement, constcharptr>
  442. {
  443. public:
  444. static HashKeyElement *createKeyElement(const char *key, bool nocase)
  445. {
  446. size32_t l = (size32_t)strlen(key);
  447. HashKeyElement *hke = (HashKeyElement *) checked_malloc(sizeof(HashKeyElement)+l+1,-605);
  448. memcpy((void *) (hke->keyPtr()), key, l+1);
  449. if (nocase)
  450. hke->hashValue = hashnc((const unsigned char *)key, l, 0);
  451. else
  452. hke->hashValue = hashc((const unsigned char *)key, l, 0);
  453. hke->linkCount = 0;
  454. return hke;
  455. }
  456. protected:
  457. CriticalSection crit;
  458. bool nocase;
  459. inline HashKeyElement *createKeyElement(const char *key)
  460. {
  461. HashKeyElement *hke = createKeyElement(key, nocase);
  462. verifyex(add(*hke));
  463. return hke;
  464. }
  465. public:
  466. IMPLEMENT_SUPERHASHTABLEOF_REF_FIND(HashKeyElement, constcharptr);
  467. AtomRefTable(bool _nocase=false) : SuperHashTableOf<HashKeyElement, constcharptr>(3000), nocase(_nocase) { }
  468. ~AtomRefTable() { _releaseAll(); }
  469. inline HashKeyElement *findLink(const char *_key)
  470. {
  471. CriticalBlock b(crit);
  472. HashKeyElement *key = find(*_key);
  473. if (key) key->linkCount++;
  474. return key;
  475. }
  476. // assumes key is member of this table.
  477. inline HashKeyElement *queryCreate(const char *_key)
  478. {
  479. CriticalBlock b(crit);
  480. HashKeyElement *key = find(*_key);
  481. if (key)
  482. key->linkCount++;
  483. else
  484. key = createKeyElement(_key);
  485. return key;
  486. }
  487. inline HashKeyElement *queryCreate(const char *_key, bool &didCreate)
  488. {
  489. CriticalBlock b(crit);
  490. HashKeyElement *key = find(*_key);
  491. if (key)
  492. {
  493. didCreate = false;
  494. key->linkCount++;
  495. }
  496. else
  497. {
  498. didCreate = true;
  499. key = createKeyElement(_key);
  500. }
  501. return key;
  502. }
  503. inline void linkKey(const char *key)
  504. {
  505. queryCreate(key);
  506. }
  507. inline bool releaseKey(HashKeyElement *key)
  508. {
  509. CriticalBlock b(crit);
  510. if (0 == key->linkCount)
  511. {
  512. verifyex(removeExact(key));
  513. return true;
  514. }
  515. --key->linkCount;
  516. return false;
  517. }
  518. protected:
  519. // SuperHashTable definitions
  520. virtual void onAdd(void *e __attribute__((unused))) { }
  521. virtual void onRemove(void *e)
  522. {
  523. free(e);
  524. }
  525. virtual unsigned getHashFromElement(const void *e) const
  526. {
  527. return ((HashKeyElement *) e)->queryHash();
  528. }
  529. virtual unsigned getHashFromFindParam(const void *fp) const
  530. {
  531. if (nocase)
  532. return hashnc((const unsigned char *)fp, (size32_t)strlen((const char *)fp), 0);
  533. else
  534. return hashc((const unsigned char *)fp, (size32_t)strlen((const char *)fp), 0);
  535. }
  536. virtual const void *getFindParam(const void *e) const
  537. {
  538. return ((HashKeyElement *) e)->get();
  539. }
  540. virtual bool matchesFindParam(const void *e, const void *fp, unsigned fphash __attribute__((unused))) const
  541. {
  542. if (nocase)
  543. return (0 == stricmp(((HashKeyElement *)e)->get(), (const char *)fp));
  544. else
  545. return (0 == strcmp(((HashKeyElement *)e)->get(), (const char *)fp));
  546. }
  547. };
  548. #endif