cc_hdict.C 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // $TOG: cc_hdict.C /main/5 1998/04/17 11:45:00 mgreess $
  2. #include "dti_cc/cc_exceptions.h"
  3. #include "dti_cc/cc_hdict.h"
  4. template <class K, class V> CC_Boolean kv_pair<K, V>::f_needRemove = FALSE;
  5. template <class K, class V>
  6. kv_pair<K, V>::~kv_pair()
  7. {
  8. if ( f_needRemove == TRUE ) {
  9. delete f_key;
  10. delete f_value;
  11. }
  12. }
  13. #ifdef DEBUG
  14. template <class K, class V>
  15. ostream& kv_pair<K, V>::print(ostream& out)
  16. {
  17. return out << *f_key << " " << *f_value << "\n";
  18. }
  19. #endif
  20. template <class K, class V>
  21. unsigned int kv_pair<K, V>::operator==(const kv_pair<K, V>& kv)
  22. {
  23. if ( f_key == 0 || kv.f_key == 0 )
  24. throw(ccStringException("kv_pair::operator==(): null pointer(s)."));
  25. return ( *f_key == (*kv.f_key) ) ? 1 : 0;
  26. }
  27. ///////////////////////////////////
  28. //
  29. ///////////////////////////////////
  30. template <class K, class V>
  31. hashTable<K,V>::hashTable(const hashTable<K, V>& h) :
  32. f_hash_func_ptr(h.f_hash_func_ptr), f_buckets(h.f_buckets),
  33. f_items(h.f_items)
  34. {
  35. cerr << "Warning: hashTable(const hashTable&) called" << endl;
  36. exit(-1);
  37. }
  38. template <class K, class V>
  39. hashTable<K,V>::hashTable(unsigned (*f)(const K&), size_t init_bucket_num) :
  40. f_hash_func_ptr(f), f_buckets(init_bucket_num),
  41. f_items(0)
  42. {
  43. }
  44. template <class K, class V>
  45. hashTable<K,V>::~hashTable()
  46. {
  47. CC_TPtrSlist<kv_pair<K, V> > * b = 0;
  48. kv_pair<K, V> * r = 0;
  49. for (size_t i=0; i<f_buckets.length(); i++ ) {
  50. b = f_buckets[i];
  51. if ( b ) {
  52. while ( (r = b -> removeFirst()) )
  53. delete r;
  54. delete b;
  55. }
  56. }
  57. }
  58. template <class K, class V>
  59. void hashTable<K,V>::clearAndDestroy()
  60. {
  61. kv_pair<K, V>::f_needRemove = TRUE;
  62. CC_TPtrSlist<kv_pair<K, V> >* b = 0;
  63. for (size_t i=0; i<f_buckets.length(); i++ ) {
  64. b = f_buckets[i];
  65. if ( b ) {
  66. b -> clearAndDestroy();
  67. delete b;
  68. f_buckets[i] = 0;
  69. }
  70. }
  71. f_items = 0;
  72. kv_pair<K, V>::f_needRemove = FALSE;
  73. }
  74. template <class K, class V>
  75. CC_Boolean hashTable<K,V>::contains(const K* k) const
  76. {
  77. if ( findValue(k) )
  78. return TRUE;
  79. else
  80. return FALSE;
  81. }
  82. template <class K, class V>
  83. kv_pair<K, V>* hashTable<K,V>::_find(const K* k) const
  84. {
  85. size_t i = (*f_hash_func_ptr)(*k) % f_buckets.length();
  86. CC_TPtrSlist<kv_pair<K, V> >* b = f_buckets[i];
  87. if ( b == 0 )
  88. return 0;
  89. kv_pair<K, V> key((K*)k);
  90. return b -> find(&key);
  91. }
  92. template <class K, class V>
  93. V* hashTable<K,V>::findValue(const K* k) const
  94. {
  95. kv_pair<K, V>* p = _find(k);
  96. if ( p )
  97. return p -> f_value;
  98. else
  99. return 0;
  100. }
  101. template <class K, class V>
  102. K* hashTable<K,V>::findKeyAndValue(const K* k, V*& v) const
  103. {
  104. kv_pair<K, V>* p = _find(k);
  105. if ( p ) {
  106. v = p -> f_value;
  107. return p -> f_key;
  108. } else
  109. return 0;
  110. }
  111. template <class K, class V>
  112. void hashTable<K,V>::insertKeyAndValue(K* k, V* v)
  113. {
  114. size_t i = (*f_hash_func_ptr)(*k) % f_buckets.length();
  115. CC_TPtrSlist<kv_pair<K, V> >* b = f_buckets[i];
  116. if ( b == 0 ) {
  117. f_buckets[i] = new CC_TPtrSlist<kv_pair<K, V> >;
  118. }
  119. kv_pair<K, V>* p = new kv_pair<K, V>(k, v);
  120. f_buckets[i] -> insert(p);
  121. f_items ++;
  122. }
  123. template <class K, class V>
  124. K* hashTable<K,V>::remove(const K* k)
  125. {
  126. size_t i = (*f_hash_func_ptr)(*k) % f_buckets.length();
  127. CC_TPtrSlist<kv_pair<K, V> >* b = f_buckets[i];
  128. if ( b == 0 )
  129. return 0;
  130. kv_pair<K, V> key((K*)k, 0);
  131. kv_pair<K, V>* result = b -> remove(&key);
  132. if ( result == 0 )
  133. return 0;
  134. K* kr = result -> f_key;
  135. delete result;
  136. f_items --;
  137. return kr;
  138. }
  139. #ifdef DEBUG
  140. template <class K, class V>
  141. ostream& hashTable<K,V>::print(ostream& out)
  142. {
  143. CC_TPtrSlist<kv_pair<K, V> >* b = 0;
  144. for (int i=0; i<f_buckets.length(); i++ ) {
  145. b = f_buckets[i];
  146. if ( b ) {
  147. cerr << "bucket num = " << i << "\n";
  148. CC_TPtrSlistIterator<kv_pair<K, V> > next(*b);
  149. while (++next) {
  150. out << ' ' << *next.key() ;
  151. }
  152. }
  153. }
  154. return out;
  155. }
  156. #endif
  157. ////////////////////////////////////////
  158. template <class K, class V>
  159. hashTableIterator<K,V>::hashTableIterator(hashTable<K, V>& b) :
  160. f_bucket_num(0), f_pos(0), f_rec(0), f_hashTable(b)
  161. {
  162. }
  163. template <class K, class V>
  164. hashTableIterator<K,V>::~hashTableIterator()
  165. {
  166. }
  167. template <class K, class V>
  168. CC_Boolean hashTableIterator<K,V>::_findNonEmptyBucket()
  169. {
  170. CC_TPtrSlist<kv_pair<K, V> >* b = 0;
  171. for (; f_bucket_num<f_hashTable.f_buckets.length(); f_bucket_num++ ) {
  172. if ( (b=f_hashTable.f_buckets[f_bucket_num]) && b->entries() > 0 ) {
  173. f_pos = 0;
  174. return TRUE;
  175. }
  176. }
  177. return FALSE;
  178. }
  179. template <class K, class V>
  180. CC_Boolean hashTableIterator<K,V>::operator++()
  181. {
  182. if ( f_rec == 0 ) { // first call to this op.
  183. if ( _findNonEmptyBucket() == FALSE )
  184. return FALSE;
  185. } else {
  186. if ( _findNextRecord() == FALSE ) {
  187. f_bucket_num++;
  188. if ( _findNonEmptyBucket() == FALSE )
  189. return FALSE;
  190. }
  191. }
  192. //fprintf(stderr, "in operator++: f_bucket_num= %d, f_pos = %d\n",
  193. //f_bucket_num, f_pos);
  194. f_rec = f_hashTable.f_buckets[f_bucket_num] -> at(f_pos);
  195. return TRUE;
  196. }
  197. template <class K, class V>
  198. CC_Boolean hashTableIterator<K,V>::_findNextRecord()
  199. {
  200. f_pos++;
  201. //fprintf(stderr, "f_bucket_num= %d, f_pos = %d, entries() = %d\n", f_bucket_num, f_pos, f_hashTable.f_buckets[f_bucket_num] -> entries() );
  202. if ( f_hashTable.f_buckets[f_bucket_num] -> entries() <= f_pos )
  203. return FALSE;
  204. else
  205. return TRUE;
  206. }
  207. template <class K, class V>
  208. K* hashTableIterator<K,V>::key()
  209. {
  210. return f_rec -> f_key;
  211. }
  212. template <class K, class V>
  213. V* hashTableIterator<K,V>::value() const
  214. {
  215. return f_rec -> f_value;
  216. }