hash_test_interface.h 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. // Copyright (c) 2010, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. // ---
  30. //
  31. // This implements a uniform interface for all 6 hash implementations:
  32. // dense_hashtable, dense_hash_map, dense_hash_set
  33. // sparse_hashtable, sparse_hash_map, sparse_hash_set
  34. // This is intended to be used for testing, to provide a single routine
  35. // that can easily test all 6 implementations.
  36. //
  37. // The main reasons to specialize are to (1) provide dummy
  38. // implementations for methods that are only needed for some of the
  39. // implementations (for instance, set_empty_key()), and (2) provide a
  40. // uniform interface to just the keys -- for instance, we provide
  41. // wrappers around the iterators that define it.key, which gives the
  42. // "key" part of the bucket (*it or it->first, depending on the class).
  43. #ifndef UTIL_GTL_HASH_TEST_INTERFACE_H_
  44. #define UTIL_GTL_HASH_TEST_INTERFACE_H_
  45. #include <sparsehash/internal/sparseconfig.h>
  46. #include <functional> // for equal_to<>
  47. #include <sparsehash/internal/sparsehashtable.h>
  48. #include <sparsehash/sparse_hash_map>
  49. #include <sparsehash/sparse_hash_set>
  50. #include <sparsehash/internal/densehashtable.h>
  51. #include <sparsehash/dense_hash_map>
  52. #include <sparsehash/dense_hash_set>
  53. #include HASH_FUN_H // for hash<>
  54. _START_GOOGLE_NAMESPACE_
  55. // This is the "default" interface, which just passes everything
  56. // through to the underlying hashtable. You'll need to subclass it to
  57. // specialize behavior for an individual hashtable.
  58. template <class HT>
  59. class BaseHashtableInterface {
  60. public:
  61. virtual ~BaseHashtableInterface() {}
  62. typedef typename HT::key_type key_type;
  63. typedef typename HT::value_type value_type;
  64. typedef typename HT::hasher hasher;
  65. typedef typename HT::key_equal key_equal;
  66. typedef typename HT::allocator_type allocator_type;
  67. typedef typename HT::size_type size_type;
  68. typedef typename HT::difference_type difference_type;
  69. typedef typename HT::pointer pointer;
  70. typedef typename HT::const_pointer const_pointer;
  71. typedef typename HT::reference reference;
  72. typedef typename HT::const_reference const_reference;
  73. class const_iterator;
  74. class iterator : public HT::iterator {
  75. public:
  76. iterator() : parent_(NULL) { } // this allows code like "iterator it;"
  77. iterator(typename HT::iterator it,
  78. const BaseHashtableInterface* parent)
  79. : HT::iterator(it), parent_(parent) { }
  80. key_type key() { return parent_->it_to_key(*this); }
  81. private:
  82. friend class BaseHashtableInterface::const_iterator; // for its ctor
  83. const BaseHashtableInterface* parent_;
  84. };
  85. class const_iterator : public HT::const_iterator {
  86. public:
  87. const_iterator() : parent_(NULL) { }
  88. const_iterator(typename HT::const_iterator it,
  89. const BaseHashtableInterface* parent)
  90. : HT::const_iterator(it), parent_(parent) { }
  91. const_iterator(typename HT::iterator it,
  92. BaseHashtableInterface* parent)
  93. : HT::const_iterator(it), parent_(parent) { }
  94. // The parameter type here *should* just be "iterator", but MSVC
  95. // gets confused by that, so I'm overly specific.
  96. const_iterator(typename BaseHashtableInterface<HT>::iterator it)
  97. : HT::const_iterator(it), parent_(it.parent_) { }
  98. key_type key() { return parent_->it_to_key(*this); }
  99. private:
  100. const BaseHashtableInterface* parent_;
  101. };
  102. class const_local_iterator;
  103. class local_iterator : public HT::local_iterator {
  104. public:
  105. local_iterator() : parent_(NULL) { }
  106. local_iterator(typename HT::local_iterator it,
  107. const BaseHashtableInterface* parent)
  108. : HT::local_iterator(it), parent_(parent) { }
  109. key_type key() { return parent_->it_to_key(*this); }
  110. private:
  111. friend class BaseHashtableInterface::const_local_iterator; // for its ctor
  112. const BaseHashtableInterface* parent_;
  113. };
  114. class const_local_iterator : public HT::const_local_iterator {
  115. public:
  116. const_local_iterator() : parent_(NULL) { }
  117. const_local_iterator(typename HT::const_local_iterator it,
  118. const BaseHashtableInterface* parent)
  119. : HT::const_local_iterator(it), parent_(parent) { }
  120. const_local_iterator(typename HT::local_iterator it,
  121. BaseHashtableInterface* parent)
  122. : HT::const_local_iterator(it), parent_(parent) { }
  123. const_local_iterator(local_iterator it)
  124. : HT::const_local_iterator(it), parent_(it.parent_) { }
  125. key_type key() { return parent_->it_to_key(*this); }
  126. private:
  127. const BaseHashtableInterface* parent_;
  128. };
  129. iterator begin() {
  130. return iterator(ht_.begin(), this);
  131. }
  132. iterator end() {
  133. return iterator(ht_.end(), this);
  134. }
  135. const_iterator begin() const {
  136. return const_iterator(ht_.begin(), this);
  137. }
  138. const_iterator end() const {
  139. return const_iterator(ht_.end(), this);
  140. }
  141. local_iterator begin(size_type i) {
  142. return local_iterator(ht_.begin(i), this);
  143. }
  144. local_iterator end(size_type i) {
  145. return local_iterator(ht_.end(i), this);
  146. }
  147. const_local_iterator begin(size_type i) const {
  148. return const_local_iterator(ht_.begin(i), this);
  149. }
  150. const_local_iterator end(size_type i) const {
  151. return const_local_iterator(ht_.end(i), this);
  152. }
  153. hasher hash_funct() const { return ht_.hash_funct(); }
  154. hasher hash_function() const { return ht_.hash_function(); }
  155. key_equal key_eq() const { return ht_.key_eq(); }
  156. allocator_type get_allocator() const { return ht_.get_allocator(); }
  157. BaseHashtableInterface(size_type expected_max_items_in_table,
  158. const hasher& hf,
  159. const key_equal& eql,
  160. const allocator_type& alloc)
  161. : ht_(expected_max_items_in_table, hf, eql, alloc) { }
  162. // Not all ht_'s support this constructor: you should only call it
  163. // from a subclass if you know your ht supports it. Otherwise call
  164. // the previous constructor, followed by 'insert(f, l);'.
  165. template <class InputIterator>
  166. BaseHashtableInterface(InputIterator f, InputIterator l,
  167. size_type expected_max_items_in_table,
  168. const hasher& hf,
  169. const key_equal& eql,
  170. const allocator_type& alloc)
  171. : ht_(f, l, expected_max_items_in_table, hf, eql, alloc) {
  172. }
  173. // This is the version of the constructor used by dense_*, which
  174. // requires an empty key in the constructor.
  175. template <class InputIterator>
  176. BaseHashtableInterface(InputIterator f, InputIterator l, key_type empty_k,
  177. size_type expected_max_items_in_table,
  178. const hasher& hf,
  179. const key_equal& eql,
  180. const allocator_type& alloc)
  181. : ht_(f, l, empty_k, expected_max_items_in_table, hf, eql, alloc) {
  182. }
  183. // This is the constructor appropriate for {dense,sparse}hashtable.
  184. template <class ExtractKey, class SetKey>
  185. BaseHashtableInterface(size_type expected_max_items_in_table,
  186. const hasher& hf,
  187. const key_equal& eql,
  188. const ExtractKey& ek,
  189. const SetKey& sk,
  190. const allocator_type& alloc)
  191. : ht_(expected_max_items_in_table, hf, eql, ek, sk, alloc) { }
  192. void clear() { ht_.clear(); }
  193. void swap(BaseHashtableInterface& other) { ht_.swap(other.ht_); }
  194. // Only part of the API for some hashtable implementations.
  195. void clear_no_resize() { clear(); }
  196. size_type size() const { return ht_.size(); }
  197. size_type max_size() const { return ht_.max_size(); }
  198. bool empty() const { return ht_.empty(); }
  199. size_type bucket_count() const { return ht_.bucket_count(); }
  200. size_type max_bucket_count() const { return ht_.max_bucket_count(); }
  201. size_type bucket_size(size_type i) const {
  202. return ht_.bucket_size(i);
  203. }
  204. size_type bucket(const key_type& key) const {
  205. return ht_.bucket(key);
  206. }
  207. float load_factor() const { return ht_.load_factor(); }
  208. float max_load_factor() const { return ht_.max_load_factor(); }
  209. void max_load_factor(float grow) { ht_.max_load_factor(grow); }
  210. float min_load_factor() const { return ht_.min_load_factor(); }
  211. void min_load_factor(float shrink) { ht_.min_load_factor(shrink); }
  212. void set_resizing_parameters(float shrink, float grow) {
  213. ht_.set_resizing_parameters(shrink, grow);
  214. }
  215. void resize(size_type hint) { ht_.resize(hint); }
  216. void rehash(size_type hint) { ht_.rehash(hint); }
  217. iterator find(const key_type& key) {
  218. return iterator(ht_.find(key), this);
  219. }
  220. const_iterator find(const key_type& key) const {
  221. return const_iterator(ht_.find(key), this);
  222. }
  223. // Rather than try to implement operator[], which doesn't make much
  224. // sense for set types, we implement two methods: bracket_equal and
  225. // bracket_assign. By default, bracket_equal(a, b) returns true if
  226. // ht[a] == b, and false otherwise. (Note that this follows
  227. // operator[] semantics exactly, including inserting a if it's not
  228. // already in the hashtable, before doing the equality test.) For
  229. // sets, which have no operator[], b is ignored, and bracket_equal
  230. // returns true if key is in the set and false otherwise.
  231. // bracket_assign(a, b) is equivalent to ht[a] = b. For sets, b is
  232. // ignored, and bracket_assign is equivalent to ht.insert(a).
  233. template<typename AssignValue>
  234. bool bracket_equal(const key_type& key, const AssignValue& expected) {
  235. return ht_[key] == expected;
  236. }
  237. template<typename AssignValue>
  238. void bracket_assign(const key_type& key, const AssignValue& value) {
  239. ht_[key] = value;
  240. }
  241. size_type count(const key_type& key) const { return ht_.count(key); }
  242. std::pair<iterator, iterator> equal_range(const key_type& key) {
  243. std::pair<typename HT::iterator, typename HT::iterator> r
  244. = ht_.equal_range(key);
  245. return std::pair<iterator, iterator>(iterator(r.first, this),
  246. iterator(r.second, this));
  247. }
  248. std::pair<const_iterator, const_iterator> equal_range(const key_type& key)
  249. const {
  250. std::pair<typename HT::const_iterator, typename HT::const_iterator> r
  251. = ht_.equal_range(key);
  252. return std::pair<const_iterator, const_iterator>(
  253. const_iterator(r.first, this), const_iterator(r.second, this));
  254. }
  255. const_iterator random_element(class ACMRandom* r) const {
  256. return const_iterator(ht_.random_element(r), this);
  257. }
  258. iterator random_element(class ACMRandom* r) {
  259. return iterator(ht_.random_element(r), this);
  260. }
  261. std::pair<iterator, bool> insert(const value_type& obj) {
  262. std::pair<typename HT::iterator, bool> r = ht_.insert(obj);
  263. return std::pair<iterator, bool>(iterator(r.first, this), r.second);
  264. }
  265. template <class InputIterator>
  266. void insert(InputIterator f, InputIterator l) {
  267. ht_.insert(f, l);
  268. }
  269. void insert(typename HT::const_iterator f, typename HT::const_iterator l) {
  270. ht_.insert(f, l);
  271. }
  272. iterator insert(typename HT::iterator, const value_type& obj) {
  273. return iterator(insert(obj).first, this);
  274. }
  275. // These will commonly need to be overridden by the child.
  276. void set_empty_key(const key_type& k) { ht_.set_empty_key(k); }
  277. void clear_empty_key() { ht_.clear_empty_key(); }
  278. key_type empty_key() const { return ht_.empty_key(); }
  279. void set_deleted_key(const key_type& k) { ht_.set_deleted_key(k); }
  280. void clear_deleted_key() { ht_.clear_deleted_key(); }
  281. key_type deleted_key() const { return ht_.deleted_key(); }
  282. size_type erase(const key_type& key) { return ht_.erase(key); }
  283. void erase(typename HT::iterator it) { ht_.erase(it); }
  284. void erase(typename HT::iterator f, typename HT::iterator l) {
  285. ht_.erase(f, l);
  286. }
  287. bool operator==(const BaseHashtableInterface& other) const {
  288. return ht_ == other.ht_;
  289. }
  290. bool operator!=(const BaseHashtableInterface& other) const {
  291. return ht_ != other.ht_;
  292. }
  293. template <typename ValueSerializer, typename OUTPUT>
  294. bool serialize(ValueSerializer serializer, OUTPUT *fp) {
  295. return ht_.serialize(serializer, fp);
  296. }
  297. template <typename ValueSerializer, typename INPUT>
  298. bool unserialize(ValueSerializer serializer, INPUT *fp) {
  299. return ht_.unserialize(serializer, fp);
  300. }
  301. template <typename OUTPUT>
  302. bool write_metadata(OUTPUT *fp) {
  303. return ht_.write_metadata(fp);
  304. }
  305. template <typename INPUT>
  306. bool read_metadata(INPUT *fp) {
  307. return ht_.read_metadata(fp);
  308. }
  309. template <typename OUTPUT>
  310. bool write_nopointer_data(OUTPUT *fp) {
  311. return ht_.write_nopointer_data(fp);
  312. }
  313. template <typename INPUT>
  314. bool read_nopointer_data(INPUT *fp) {
  315. return ht_.read_nopointer_data(fp);
  316. }
  317. // low-level stats
  318. int num_table_copies() const { return ht_.num_table_copies(); }
  319. // Not part of the hashtable API, but is provided to make testing easier.
  320. virtual key_type get_key(const value_type& value) const = 0;
  321. // All subclasses should define get_data(value_type) as well. I don't
  322. // provide an abstract-virtual definition here, because the return type
  323. // differs between subclasses (not all subclasses define data_type).
  324. //virtual data_type get_data(const value_type& value) const = 0;
  325. //virtual data_type default_data() const = 0;
  326. // These allow introspection into the interface. "Supports" means
  327. // that the implementation of this functionality isn't a noop.
  328. virtual bool supports_clear_no_resize() const = 0;
  329. virtual bool supports_empty_key() const = 0;
  330. virtual bool supports_deleted_key() const = 0;
  331. virtual bool supports_brackets() const = 0; // has a 'real' operator[]
  332. virtual bool supports_readwrite() const = 0;
  333. virtual bool supports_num_table_copies() const = 0;
  334. virtual bool supports_serialization() const = 0;
  335. protected:
  336. HT ht_;
  337. // These are what subclasses have to define to get class-specific behavior
  338. virtual key_type it_to_key(const iterator& it) const = 0;
  339. virtual key_type it_to_key(const const_iterator& it) const = 0;
  340. virtual key_type it_to_key(const local_iterator& it) const = 0;
  341. virtual key_type it_to_key(const const_local_iterator& it) const = 0;
  342. };
  343. // ---------------------------------------------------------------------
  344. template <class Key, class T,
  345. class HashFcn = SPARSEHASH_HASH<Key>,
  346. class EqualKey = std::equal_to<Key>,
  347. class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
  348. class HashtableInterface_SparseHashMap
  349. : public BaseHashtableInterface< sparse_hash_map<Key, T, HashFcn,
  350. EqualKey, Alloc> > {
  351. private:
  352. typedef sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
  353. typedef BaseHashtableInterface<ht> p; // parent
  354. public:
  355. explicit HashtableInterface_SparseHashMap(
  356. typename p::size_type expected_max_items = 0,
  357. const typename p::hasher& hf = typename p::hasher(),
  358. const typename p::key_equal& eql = typename p::key_equal(),
  359. const typename p::allocator_type& alloc = typename p::allocator_type())
  360. : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
  361. template <class InputIterator>
  362. HashtableInterface_SparseHashMap(
  363. InputIterator f, InputIterator l,
  364. typename p::size_type expected_max_items = 0,
  365. const typename p::hasher& hf = typename p::hasher(),
  366. const typename p::key_equal& eql = typename p::key_equal(),
  367. const typename p::allocator_type& alloc = typename p::allocator_type())
  368. : BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
  369. typename p::key_type get_key(const typename p::value_type& value) const {
  370. return value.first;
  371. }
  372. typename ht::data_type get_data(const typename p::value_type& value) const {
  373. return value.second;
  374. }
  375. typename ht::data_type default_data() const {
  376. return typename ht::data_type();
  377. }
  378. bool supports_clear_no_resize() const { return false; }
  379. bool supports_empty_key() const { return false; }
  380. bool supports_deleted_key() const { return true; }
  381. bool supports_brackets() const { return true; }
  382. bool supports_readwrite() const { return true; }
  383. bool supports_num_table_copies() const { return false; }
  384. bool supports_serialization() const { return true; }
  385. void set_empty_key(const typename p::key_type&) { }
  386. void clear_empty_key() { }
  387. typename p::key_type empty_key() const { return typename p::key_type(); }
  388. int num_table_copies() const { return 0; }
  389. typedef typename ht::NopointerSerializer NopointerSerializer;
  390. protected:
  391. template <class K2, class T2, class H2, class E2, class A2>
  392. friend void swap(HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& a,
  393. HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& b);
  394. typename p::key_type it_to_key(const typename p::iterator& it) const {
  395. return it->first;
  396. }
  397. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  398. return it->first;
  399. }
  400. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  401. return it->first;
  402. }
  403. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  404. const {
  405. return it->first;
  406. }
  407. };
  408. template <class K, class T, class H, class E, class A>
  409. void swap(HashtableInterface_SparseHashMap<K,T,H,E,A>& a,
  410. HashtableInterface_SparseHashMap<K,T,H,E,A>& b) {
  411. swap(a.ht_, b.ht_);
  412. }
  413. // ---------------------------------------------------------------------
  414. template <class Value,
  415. class HashFcn = SPARSEHASH_HASH<Value>,
  416. class EqualKey = std::equal_to<Value>,
  417. class Alloc = libc_allocator_with_realloc<Value> >
  418. class HashtableInterface_SparseHashSet
  419. : public BaseHashtableInterface< sparse_hash_set<Value, HashFcn,
  420. EqualKey, Alloc> > {
  421. private:
  422. typedef sparse_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
  423. typedef BaseHashtableInterface<ht> p; // parent
  424. public:
  425. // Bizarrely, MSVC 8.0 has trouble with the (perfectly fine)
  426. // typename's in this constructor, and this constructor alone, out
  427. // of all the ones in the file. So for MSVC, we take some typenames
  428. // out, which is technically invalid C++, but MSVC doesn't seem to
  429. // mind.
  430. #ifdef _MSC_VER
  431. explicit HashtableInterface_SparseHashSet(
  432. typename p::size_type expected_max_items = 0,
  433. const typename p::hasher& hf = p::hasher(),
  434. const typename p::key_equal& eql = p::key_equal(),
  435. const typename p::allocator_type& alloc = p::allocator_type())
  436. : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
  437. #else
  438. explicit HashtableInterface_SparseHashSet(
  439. typename p::size_type expected_max_items = 0,
  440. const typename p::hasher& hf = typename p::hasher(),
  441. const typename p::key_equal& eql = typename p::key_equal(),
  442. const typename p::allocator_type& alloc = typename p::allocator_type())
  443. : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
  444. #endif
  445. template <class InputIterator>
  446. HashtableInterface_SparseHashSet(
  447. InputIterator f, InputIterator l,
  448. typename p::size_type expected_max_items = 0,
  449. const typename p::hasher& hf = typename p::hasher(),
  450. const typename p::key_equal& eql = typename p::key_equal(),
  451. const typename p::allocator_type& alloc = typename p::allocator_type())
  452. : BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
  453. template<typename AssignValue>
  454. bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
  455. return this->ht_.find(key) != this->ht_.end();
  456. }
  457. template<typename AssignValue>
  458. void bracket_assign(const typename p::key_type& key, const AssignValue&) {
  459. this->ht_.insert(key);
  460. }
  461. typename p::key_type get_key(const typename p::value_type& value) const {
  462. return value;
  463. }
  464. // For sets, the only 'data' is that an item is actually inserted.
  465. bool get_data(const typename p::value_type&) const {
  466. return true;
  467. }
  468. bool default_data() const {
  469. return true;
  470. }
  471. bool supports_clear_no_resize() const { return false; }
  472. bool supports_empty_key() const { return false; }
  473. bool supports_deleted_key() const { return true; }
  474. bool supports_brackets() const { return false; }
  475. bool supports_readwrite() const { return true; }
  476. bool supports_num_table_copies() const { return false; }
  477. bool supports_serialization() const { return true; }
  478. void set_empty_key(const typename p::key_type&) { }
  479. void clear_empty_key() { }
  480. typename p::key_type empty_key() const { return typename p::key_type(); }
  481. int num_table_copies() const { return 0; }
  482. typedef typename ht::NopointerSerializer NopointerSerializer;
  483. protected:
  484. template <class K2, class H2, class E2, class A2>
  485. friend void swap(HashtableInterface_SparseHashSet<K2,H2,E2,A2>& a,
  486. HashtableInterface_SparseHashSet<K2,H2,E2,A2>& b);
  487. typename p::key_type it_to_key(const typename p::iterator& it) const {
  488. return *it;
  489. }
  490. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  491. return *it;
  492. }
  493. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  494. return *it;
  495. }
  496. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  497. const {
  498. return *it;
  499. }
  500. };
  501. template <class K, class H, class E, class A>
  502. void swap(HashtableInterface_SparseHashSet<K,H,E,A>& a,
  503. HashtableInterface_SparseHashSet<K,H,E,A>& b) {
  504. swap(a.ht_, b.ht_);
  505. }
  506. // ---------------------------------------------------------------------
  507. template <class Value, class Key, class HashFcn, class ExtractKey,
  508. class SetKey, class EqualKey, class Alloc>
  509. class HashtableInterface_SparseHashtable
  510. : public BaseHashtableInterface< sparse_hashtable<Value, Key, HashFcn,
  511. ExtractKey, SetKey,
  512. EqualKey, Alloc> > {
  513. private:
  514. typedef sparse_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
  515. EqualKey, Alloc> ht;
  516. typedef BaseHashtableInterface<ht> p; // parent
  517. public:
  518. explicit HashtableInterface_SparseHashtable(
  519. typename p::size_type expected_max_items = 0,
  520. const typename p::hasher& hf = typename p::hasher(),
  521. const typename p::key_equal& eql = typename p::key_equal(),
  522. const typename p::allocator_type& alloc = typename p::allocator_type())
  523. : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
  524. ExtractKey(), SetKey(), alloc) { }
  525. template <class InputIterator>
  526. HashtableInterface_SparseHashtable(
  527. InputIterator f, InputIterator l,
  528. typename p::size_type expected_max_items = 0,
  529. const typename p::hasher& hf = typename p::hasher(),
  530. const typename p::key_equal& eql = typename p::key_equal(),
  531. const typename p::allocator_type& alloc = typename p::allocator_type())
  532. : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
  533. ExtractKey(), SetKey(), alloc) {
  534. this->insert(f, l);
  535. }
  536. float max_load_factor() const {
  537. float shrink, grow;
  538. this->ht_.get_resizing_parameters(&shrink, &grow);
  539. return grow;
  540. }
  541. void max_load_factor(float new_grow) {
  542. float shrink, grow;
  543. this->ht_.get_resizing_parameters(&shrink, &grow);
  544. this->ht_.set_resizing_parameters(shrink, new_grow);
  545. }
  546. float min_load_factor() const {
  547. float shrink, grow;
  548. this->ht_.get_resizing_parameters(&shrink, &grow);
  549. return shrink;
  550. }
  551. void min_load_factor(float new_shrink) {
  552. float shrink, grow;
  553. this->ht_.get_resizing_parameters(&shrink, &grow);
  554. this->ht_.set_resizing_parameters(new_shrink, grow);
  555. }
  556. template<typename AssignValue>
  557. bool bracket_equal(const typename p::key_type&, const AssignValue&) {
  558. return false;
  559. }
  560. template<typename AssignValue>
  561. void bracket_assign(const typename p::key_type&, const AssignValue&) {
  562. }
  563. typename p::key_type get_key(const typename p::value_type& value) const {
  564. return extract_key(value);
  565. }
  566. typename p::value_type get_data(const typename p::value_type& value) const {
  567. return value;
  568. }
  569. typename p::value_type default_data() const {
  570. return typename p::value_type();
  571. }
  572. bool supports_clear_no_resize() const { return false; }
  573. bool supports_empty_key() const { return false; }
  574. bool supports_deleted_key() const { return true; }
  575. bool supports_brackets() const { return false; }
  576. bool supports_readwrite() const { return true; }
  577. bool supports_num_table_copies() const { return true; }
  578. bool supports_serialization() const { return true; }
  579. void set_empty_key(const typename p::key_type&) { }
  580. void clear_empty_key() { }
  581. typename p::key_type empty_key() const { return typename p::key_type(); }
  582. // These tr1 names aren't defined for sparse_hashtable.
  583. typename p::hasher hash_function() { return this->hash_funct(); }
  584. void rehash(typename p::size_type hint) { this->resize(hint); }
  585. // TODO(csilvers): also support/test destructive_begin()/destructive_end()?
  586. typedef typename ht::NopointerSerializer NopointerSerializer;
  587. protected:
  588. template <class V2, class K2, class HF2, class EK2, class SK2, class Eq2,
  589. class A2>
  590. friend void swap(
  591. HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& a,
  592. HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& b);
  593. typename p::key_type it_to_key(const typename p::iterator& it) const {
  594. return extract_key(*it);
  595. }
  596. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  597. return extract_key(*it);
  598. }
  599. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  600. return extract_key(*it);
  601. }
  602. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  603. const {
  604. return extract_key(*it);
  605. }
  606. private:
  607. ExtractKey extract_key;
  608. };
  609. template <class V, class K, class HF, class EK, class SK, class Eq, class A>
  610. void swap(HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& a,
  611. HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& b) {
  612. swap(a.ht_, b.ht_);
  613. }
  614. // ---------------------------------------------------------------------
  615. // Unlike dense_hash_map, the wrapper class takes an extra template
  616. // value saying what the empty key is.
  617. template <class Key, class T, const Key& EMPTY_KEY,
  618. class HashFcn = SPARSEHASH_HASH<Key>,
  619. class EqualKey = std::equal_to<Key>,
  620. class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
  621. class HashtableInterface_DenseHashMap
  622. : public BaseHashtableInterface< dense_hash_map<Key, T, HashFcn,
  623. EqualKey, Alloc> > {
  624. private:
  625. typedef dense_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
  626. typedef BaseHashtableInterface<ht> p; // parent
  627. public:
  628. explicit HashtableInterface_DenseHashMap(
  629. typename p::size_type expected_max_items = 0,
  630. const typename p::hasher& hf = typename p::hasher(),
  631. const typename p::key_equal& eql = typename p::key_equal(),
  632. const typename p::allocator_type& alloc = typename p::allocator_type())
  633. : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
  634. this->set_empty_key(EMPTY_KEY);
  635. }
  636. template <class InputIterator>
  637. HashtableInterface_DenseHashMap(
  638. InputIterator f, InputIterator l,
  639. typename p::size_type expected_max_items = 0,
  640. const typename p::hasher& hf = typename p::hasher(),
  641. const typename p::key_equal& eql = typename p::key_equal(),
  642. const typename p::allocator_type& alloc = typename p::allocator_type())
  643. : BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
  644. expected_max_items, hf, eql, alloc) {
  645. }
  646. void clear_no_resize() { this->ht_.clear_no_resize(); }
  647. typename p::key_type get_key(const typename p::value_type& value) const {
  648. return value.first;
  649. }
  650. typename ht::data_type get_data(const typename p::value_type& value) const {
  651. return value.second;
  652. }
  653. typename ht::data_type default_data() const {
  654. return typename ht::data_type();
  655. }
  656. bool supports_clear_no_resize() const { return true; }
  657. bool supports_empty_key() const { return true; }
  658. bool supports_deleted_key() const { return true; }
  659. bool supports_brackets() const { return true; }
  660. bool supports_readwrite() const { return false; }
  661. bool supports_num_table_copies() const { return false; }
  662. bool supports_serialization() const { return true; }
  663. typedef typename ht::NopointerSerializer NopointerSerializer;
  664. template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
  665. template <typename INPUT> bool read_metadata(INPUT *) { return false; }
  666. template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
  667. return false;
  668. }
  669. template <typename INPUT> bool read_nopointer_data(INPUT *) {
  670. return false;
  671. }
  672. int num_table_copies() const { return 0; }
  673. protected:
  674. template <class K2, class T2, const K2& Empty2, class H2, class E2, class A2>
  675. friend void swap(HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& a,
  676. HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& b);
  677. typename p::key_type it_to_key(const typename p::iterator& it) const {
  678. return it->first;
  679. }
  680. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  681. return it->first;
  682. }
  683. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  684. return it->first;
  685. }
  686. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  687. const {
  688. return it->first;
  689. }
  690. };
  691. template <class K, class T, const K& Empty, class H, class E, class A>
  692. void swap(HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& a,
  693. HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& b) {
  694. swap(a.ht_, b.ht_);
  695. }
  696. // ---------------------------------------------------------------------
  697. // Unlike dense_hash_set, the wrapper class takes an extra template
  698. // value saying what the empty key is.
  699. template <class Value, const Value& EMPTY_KEY,
  700. class HashFcn = SPARSEHASH_HASH<Value>,
  701. class EqualKey = std::equal_to<Value>,
  702. class Alloc = libc_allocator_with_realloc<Value> >
  703. class HashtableInterface_DenseHashSet
  704. : public BaseHashtableInterface< dense_hash_set<Value, HashFcn,
  705. EqualKey, Alloc> > {
  706. private:
  707. typedef dense_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
  708. typedef BaseHashtableInterface<ht> p; // parent
  709. public:
  710. explicit HashtableInterface_DenseHashSet(
  711. typename p::size_type expected_max_items = 0,
  712. const typename p::hasher& hf = typename p::hasher(),
  713. const typename p::key_equal& eql = typename p::key_equal(),
  714. const typename p::allocator_type& alloc = typename p::allocator_type())
  715. : BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
  716. this->set_empty_key(EMPTY_KEY);
  717. }
  718. template <class InputIterator>
  719. HashtableInterface_DenseHashSet(
  720. InputIterator f, InputIterator l,
  721. typename p::size_type expected_max_items = 0,
  722. const typename p::hasher& hf = typename p::hasher(),
  723. const typename p::key_equal& eql = typename p::key_equal(),
  724. const typename p::allocator_type& alloc = typename p::allocator_type())
  725. : BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
  726. expected_max_items, hf, eql, alloc) {
  727. }
  728. void clear_no_resize() { this->ht_.clear_no_resize(); }
  729. template<typename AssignValue>
  730. bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
  731. return this->ht_.find(key) != this->ht_.end();
  732. }
  733. template<typename AssignValue>
  734. void bracket_assign(const typename p::key_type& key, const AssignValue&) {
  735. this->ht_.insert(key);
  736. }
  737. typename p::key_type get_key(const typename p::value_type& value) const {
  738. return value;
  739. }
  740. bool get_data(const typename p::value_type&) const {
  741. return true;
  742. }
  743. bool default_data() const {
  744. return true;
  745. }
  746. bool supports_clear_no_resize() const { return true; }
  747. bool supports_empty_key() const { return true; }
  748. bool supports_deleted_key() const { return true; }
  749. bool supports_brackets() const { return false; }
  750. bool supports_readwrite() const { return false; }
  751. bool supports_num_table_copies() const { return false; }
  752. bool supports_serialization() const { return true; }
  753. typedef typename ht::NopointerSerializer NopointerSerializer;
  754. template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
  755. template <typename INPUT> bool read_metadata(INPUT *) { return false; }
  756. template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
  757. return false;
  758. }
  759. template <typename INPUT> bool read_nopointer_data(INPUT *) {
  760. return false;
  761. }
  762. int num_table_copies() const { return 0; }
  763. protected:
  764. template <class K2, const K2& Empty2, class H2, class E2, class A2>
  765. friend void swap(HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& a,
  766. HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& b);
  767. typename p::key_type it_to_key(const typename p::iterator& it) const {
  768. return *it;
  769. }
  770. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  771. return *it;
  772. }
  773. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  774. return *it;
  775. }
  776. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  777. const {
  778. return *it;
  779. }
  780. };
  781. template <class K, const K& Empty, class H, class E, class A>
  782. void swap(HashtableInterface_DenseHashSet<K,Empty,H,E,A>& a,
  783. HashtableInterface_DenseHashSet<K,Empty,H,E,A>& b) {
  784. swap(a.ht_, b.ht_);
  785. }
  786. // ---------------------------------------------------------------------
  787. // Unlike dense_hashtable, the wrapper class takes an extra template
  788. // value saying what the empty key is.
  789. template <class Value, class Key, const Key& EMPTY_KEY, class HashFcn,
  790. class ExtractKey, class SetKey, class EqualKey, class Alloc>
  791. class HashtableInterface_DenseHashtable
  792. : public BaseHashtableInterface< dense_hashtable<Value, Key, HashFcn,
  793. ExtractKey, SetKey,
  794. EqualKey, Alloc> > {
  795. private:
  796. typedef dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
  797. EqualKey, Alloc> ht;
  798. typedef BaseHashtableInterface<ht> p; // parent
  799. public:
  800. explicit HashtableInterface_DenseHashtable(
  801. typename p::size_type expected_max_items = 0,
  802. const typename p::hasher& hf = typename p::hasher(),
  803. const typename p::key_equal& eql = typename p::key_equal(),
  804. const typename p::allocator_type& alloc = typename p::allocator_type())
  805. : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
  806. ExtractKey(), SetKey(), alloc) {
  807. this->set_empty_key(EMPTY_KEY);
  808. }
  809. template <class InputIterator>
  810. HashtableInterface_DenseHashtable(
  811. InputIterator f, InputIterator l,
  812. typename p::size_type expected_max_items = 0,
  813. const typename p::hasher& hf = typename p::hasher(),
  814. const typename p::key_equal& eql = typename p::key_equal(),
  815. const typename p::allocator_type& alloc = typename p::allocator_type())
  816. : BaseHashtableInterface<ht>(expected_max_items, hf, eql,
  817. ExtractKey(), SetKey(), alloc) {
  818. this->set_empty_key(EMPTY_KEY);
  819. this->insert(f, l);
  820. }
  821. void clear_no_resize() { this->ht_.clear_no_resize(); }
  822. float max_load_factor() const {
  823. float shrink, grow;
  824. this->ht_.get_resizing_parameters(&shrink, &grow);
  825. return grow;
  826. }
  827. void max_load_factor(float new_grow) {
  828. float shrink, grow;
  829. this->ht_.get_resizing_parameters(&shrink, &grow);
  830. this->ht_.set_resizing_parameters(shrink, new_grow);
  831. }
  832. float min_load_factor() const {
  833. float shrink, grow;
  834. this->ht_.get_resizing_parameters(&shrink, &grow);
  835. return shrink;
  836. }
  837. void min_load_factor(float new_shrink) {
  838. float shrink, grow;
  839. this->ht_.get_resizing_parameters(&shrink, &grow);
  840. this->ht_.set_resizing_parameters(new_shrink, grow);
  841. }
  842. template<typename AssignValue>
  843. bool bracket_equal(const typename p::key_type&, const AssignValue&) {
  844. return false;
  845. }
  846. template<typename AssignValue>
  847. void bracket_assign(const typename p::key_type&, const AssignValue&) {
  848. }
  849. typename p::key_type get_key(const typename p::value_type& value) const {
  850. return extract_key(value);
  851. }
  852. typename p::value_type get_data(const typename p::value_type& value) const {
  853. return value;
  854. }
  855. typename p::value_type default_data() const {
  856. return typename p::value_type();
  857. }
  858. bool supports_clear_no_resize() const { return true; }
  859. bool supports_empty_key() const { return true; }
  860. bool supports_deleted_key() const { return true; }
  861. bool supports_brackets() const { return false; }
  862. bool supports_readwrite() const { return false; }
  863. bool supports_num_table_copies() const { return true; }
  864. bool supports_serialization() const { return true; }
  865. typedef typename ht::NopointerSerializer NopointerSerializer;
  866. template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
  867. template <typename INPUT> bool read_metadata(INPUT *) { return false; }
  868. template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
  869. return false;
  870. }
  871. template <typename INPUT> bool read_nopointer_data(INPUT *) {
  872. return false;
  873. }
  874. // These tr1 names aren't defined for dense_hashtable.
  875. typename p::hasher hash_function() { return this->hash_funct(); }
  876. void rehash(typename p::size_type hint) { this->resize(hint); }
  877. protected:
  878. template <class V2, class K2, const K2& Empty2,
  879. class HF2, class EK2, class SK2, class Eq2, class A2>
  880. friend void swap(
  881. HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& a,
  882. HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& b);
  883. typename p::key_type it_to_key(const typename p::iterator& it) const {
  884. return extract_key(*it);
  885. }
  886. typename p::key_type it_to_key(const typename p::const_iterator& it) const {
  887. return extract_key(*it);
  888. }
  889. typename p::key_type it_to_key(const typename p::local_iterator& it) const {
  890. return extract_key(*it);
  891. }
  892. typename p::key_type it_to_key(const typename p::const_local_iterator& it)
  893. const {
  894. return extract_key(*it);
  895. }
  896. private:
  897. ExtractKey extract_key;
  898. };
  899. template <class V, class K, const K& Empty,
  900. class HF, class EK, class SK, class Eq, class A>
  901. void swap(HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& a,
  902. HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& b) {
  903. swap(a.ht_, b.ht_);
  904. }
  905. _END_GOOGLE_NAMESPACE_
  906. #endif // UTIL_GTL_HASH_TEST_INTERFACE_H_