hash_set.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #pragma once
  2. #include "fwd.h"
  3. #include "hash.h"
  4. #include <initializer_list>
  5. #include <utility>
  6. #undef value_type
  7. template <class Value, class HashFcn, class EqualKey, class Alloc>
  8. class THashSet {
  9. private:
  10. using ht = THashTable<Value, Value, HashFcn, ::TIdentity, EqualKey, Alloc>;
  11. ht rep;
  12. using mutable_iterator = typename ht::iterator;
  13. public:
  14. using key_type = typename ht::key_type;
  15. using value_type = typename ht::value_type;
  16. using hasher = typename ht::hasher;
  17. using key_equal = typename ht::key_equal;
  18. using allocator_type = typename ht::allocator_type;
  19. using node_allocator_type = typename ht::node_allocator_type;
  20. using size_type = typename ht::size_type;
  21. using difference_type = typename ht::difference_type;
  22. using pointer = typename ht::const_pointer;
  23. using const_pointer = typename ht::const_pointer;
  24. using reference = typename ht::const_reference;
  25. using const_reference = typename ht::const_reference;
  26. using iterator = typename ht::const_iterator;
  27. using const_iterator = typename ht::const_iterator;
  28. using insert_ctx = typename ht::insert_ctx;
  29. hasher hash_function() const {
  30. return rep.hash_function();
  31. }
  32. key_equal key_eq() const {
  33. return rep.key_eq();
  34. }
  35. public:
  36. THashSet() {
  37. }
  38. template <class TT>
  39. explicit THashSet(TT* allocParam, size_type n = 0)
  40. : rep(n, hasher(), key_equal(), allocParam)
  41. {
  42. }
  43. explicit THashSet(size_type n)
  44. : rep(n, hasher(), key_equal())
  45. {
  46. }
  47. THashSet(size_type n, const hasher& hf)
  48. : rep(n, hf, key_equal())
  49. {
  50. }
  51. THashSet(size_type n, const hasher& hf, const key_equal& eql)
  52. : rep(n, hf, eql)
  53. {
  54. }
  55. THashSet(std::initializer_list<value_type> list)
  56. : rep(list.size(), hasher(), key_equal())
  57. {
  58. rep.insert_unique(list.begin(), list.end());
  59. }
  60. THashSet(std::initializer_list<value_type> list, size_type n)
  61. : rep(n, hasher(), key_equal())
  62. {
  63. rep.insert_unique(list.begin(), list.end());
  64. }
  65. THashSet(std::initializer_list<value_type> list, size_type n, const hasher& hf)
  66. : rep(n, hf, key_equal())
  67. {
  68. rep.insert_unique(list.begin(), list.end());
  69. }
  70. THashSet(std::initializer_list<value_type> list, size_type n, const hasher& hf, const key_equal& eql)
  71. : rep(n, hf, eql)
  72. {
  73. rep.insert_unique(list.begin(), list.end());
  74. }
  75. template <class InputIterator>
  76. THashSet(InputIterator f, InputIterator l)
  77. : rep(0, hasher(), key_equal())
  78. {
  79. rep.insert_unique(f, l);
  80. }
  81. template <class InputIterator>
  82. THashSet(InputIterator f, InputIterator l, size_type n)
  83. : rep(n, hasher(), key_equal())
  84. {
  85. rep.insert_unique(f, l);
  86. }
  87. template <class InputIterator>
  88. THashSet(InputIterator f, InputIterator l, size_type n,
  89. const hasher& hf)
  90. : rep(n, hf, key_equal())
  91. {
  92. rep.insert_unique(f, l);
  93. }
  94. template <class InputIterator>
  95. THashSet(InputIterator f, InputIterator l, size_type n,
  96. const hasher& hf, const key_equal& eql)
  97. : rep(n, hf, eql)
  98. {
  99. rep.insert_unique(f, l);
  100. }
  101. // THashSet has implicit copy/move constructors and copy-/move-assignment operators
  102. // because its implementation is backed by THashTable.
  103. // See hash_ut.cpp
  104. public:
  105. size_type size() const {
  106. return rep.size();
  107. }
  108. size_type max_size() const {
  109. return rep.max_size();
  110. }
  111. Y_PURE_FUNCTION bool empty() const {
  112. return rep.empty();
  113. }
  114. explicit operator bool() const noexcept {
  115. return !empty();
  116. }
  117. void swap(THashSet& hs) {
  118. rep.swap(hs.rep);
  119. }
  120. iterator begin() const {
  121. return rep.begin();
  122. }
  123. iterator end() const {
  124. return rep.end();
  125. }
  126. iterator cbegin() const {
  127. return rep.begin();
  128. }
  129. iterator cend() const {
  130. return rep.end();
  131. }
  132. public:
  133. void insert(std::initializer_list<value_type> ilist) {
  134. insert(ilist.begin(), ilist.end());
  135. }
  136. template <class InputIterator>
  137. void insert(InputIterator f, InputIterator l) {
  138. rep.insert_unique(f, l);
  139. }
  140. std::pair<iterator, bool> insert(const value_type& obj) {
  141. std::pair<mutable_iterator, bool> p = rep.insert_unique(obj);
  142. return std::pair<iterator, bool>(p.first, p.second);
  143. }
  144. template <typename... Args>
  145. std::pair<iterator, bool> emplace(Args&&... args) {
  146. std::pair<mutable_iterator, bool> p = rep.emplace_unique(std::forward<Args>(args)...);
  147. return std::pair<iterator, bool>(p.first, p.second);
  148. }
  149. iterator insert(const_iterator, const value_type& obj) { // insert_hint
  150. std::pair<mutable_iterator, bool> p = rep.insert_unique(obj);
  151. return p.first;
  152. }
  153. std::pair<iterator, bool> insert_noresize(const value_type& obj) {
  154. std::pair<mutable_iterator, bool> p = rep.insert_unique_noresize(obj);
  155. return std::pair<iterator, bool>(p.first, p.second);
  156. }
  157. template <typename... Args>
  158. std::pair<iterator, bool> emplace_noresize(Args&&... args) {
  159. std::pair<mutable_iterator, bool> p = rep.emplace_unique_noresize(std::forward<Args>(args)...);
  160. return std::pair<iterator, bool>(p.first, p.second);
  161. }
  162. template <class TheObj>
  163. iterator insert_direct(const TheObj& obj, const insert_ctx& ins) {
  164. return rep.insert_direct(obj, ins);
  165. }
  166. template <typename... Args>
  167. iterator emplace_direct(const insert_ctx& ins, Args&&... args) {
  168. return rep.emplace_direct(ins, std::forward<Args>(args)...);
  169. }
  170. template <class TheKey>
  171. const_iterator find(const TheKey& key) const {
  172. return rep.find(key);
  173. }
  174. template <class TheKey>
  175. iterator find(const TheKey& key, insert_ctx& ins) {
  176. return rep.find_i(key, ins);
  177. }
  178. template <class TheKey>
  179. bool contains(const TheKey& key) const {
  180. return rep.find(key) != rep.end();
  181. }
  182. template <class TheKey>
  183. bool contains(const TheKey& key, insert_ctx& ins) {
  184. return rep.find_i(key, ins) != rep.end();
  185. }
  186. template <class TKey>
  187. size_type count(const TKey& key) const {
  188. return rep.count(key);
  189. }
  190. template <class TKey>
  191. std::pair<iterator, iterator> equal_range(const TKey& key) const {
  192. return rep.equal_range(key);
  193. }
  194. size_type erase(const key_type& key) {
  195. return rep.erase(key);
  196. }
  197. void erase(iterator it) {
  198. rep.erase(it);
  199. }
  200. void erase(iterator f, iterator l) {
  201. rep.erase(f, l);
  202. }
  203. void clear() {
  204. rep.clear();
  205. }
  206. void clear(size_t downsize_hint) {
  207. rep.clear(downsize_hint);
  208. }
  209. void basic_clear() {
  210. rep.basic_clear();
  211. }
  212. void release_nodes() {
  213. rep.release_nodes();
  214. }
  215. template <class KeySaver>
  216. int save_for_st(IOutputStream* stream, KeySaver& ks) const {
  217. return rep.template save_for_st<KeySaver>(stream, ks);
  218. }
  219. public:
  220. void reserve(size_type hint) {
  221. rep.reserve(hint);
  222. }
  223. size_type bucket_count() const {
  224. return rep.bucket_count();
  225. }
  226. size_type bucket_size(size_type n) const {
  227. return rep.bucket_size(n);
  228. }
  229. node_allocator_type& GetNodeAllocator() {
  230. return rep.GetNodeAllocator();
  231. }
  232. };
  233. template <class Value, class HashFcn, class EqualKey, class Alloc>
  234. inline bool operator==(const THashSet<Value, HashFcn, EqualKey, Alloc>& hs1, const THashSet<Value, HashFcn, EqualKey, Alloc>& hs2) {
  235. if (hs1.size() != hs2.size()) {
  236. return false;
  237. }
  238. for (const auto& it : hs1) {
  239. if (!hs2.contains(it)) {
  240. return false;
  241. }
  242. }
  243. return true;
  244. }
  245. template <class Value, class HashFcn, class EqualKey, class Alloc>
  246. inline bool operator!=(const THashSet<Value, HashFcn, EqualKey, Alloc>& hs1, const THashSet<Value, HashFcn, EqualKey, Alloc>& hs2) {
  247. return !(hs1 == hs2);
  248. }
  249. template <class Value, class HashFcn, class EqualKey, class Alloc>
  250. class THashMultiSet {
  251. private:
  252. using ht = THashTable<Value, Value, HashFcn, ::TIdentity, EqualKey, Alloc>;
  253. ht rep;
  254. public:
  255. using key_type = typename ht::key_type;
  256. using value_type = typename ht::value_type;
  257. using hasher = typename ht::hasher;
  258. using key_equal = typename ht::key_equal;
  259. using allocator_type = typename ht::allocator_type;
  260. using node_allocator_type = typename ht::node_allocator_type;
  261. using size_type = typename ht::size_type;
  262. using difference_type = typename ht::difference_type;
  263. using pointer = typename ht::const_pointer;
  264. using const_pointer = typename ht::const_pointer;
  265. using reference = typename ht::const_reference;
  266. using const_reference = typename ht::const_reference;
  267. using iterator = typename ht::const_iterator;
  268. using const_iterator = typename ht::const_iterator;
  269. hasher hash_function() const {
  270. return rep.hash_function();
  271. }
  272. key_equal key_eq() const {
  273. return rep.key_eq();
  274. }
  275. public:
  276. THashMultiSet()
  277. : rep(0, hasher(), key_equal())
  278. {
  279. }
  280. explicit THashMultiSet(size_type n)
  281. : rep(n, hasher(), key_equal())
  282. {
  283. }
  284. THashMultiSet(size_type n, const hasher& hf)
  285. : rep(n, hf, key_equal())
  286. {
  287. }
  288. THashMultiSet(size_type n, const hasher& hf, const key_equal& eql)
  289. : rep(n, hf, eql)
  290. {
  291. }
  292. template <class InputIterator>
  293. THashMultiSet(InputIterator f, InputIterator l)
  294. : rep(0, hasher(), key_equal())
  295. {
  296. rep.insert_equal(f, l);
  297. }
  298. template <class InputIterator>
  299. THashMultiSet(InputIterator f, InputIterator l, size_type n)
  300. : rep(n, hasher(), key_equal())
  301. {
  302. rep.insert_equal(f, l);
  303. }
  304. template <class InputIterator>
  305. THashMultiSet(InputIterator f, InputIterator l, size_type n,
  306. const hasher& hf)
  307. : rep(n, hf, key_equal())
  308. {
  309. rep.insert_equal(f, l);
  310. }
  311. template <class InputIterator>
  312. THashMultiSet(InputIterator f, InputIterator l, size_type n,
  313. const hasher& hf, const key_equal& eql)
  314. : rep(n, hf, eql)
  315. {
  316. rep.insert_equal(f, l);
  317. }
  318. THashMultiSet(std::initializer_list<value_type> list)
  319. : rep(list.size(), hasher(), key_equal())
  320. {
  321. rep.insert_equal(list.begin(), list.end());
  322. }
  323. // THashMultiSet has implicit copy/move constructors and copy-/move-assignment operators
  324. // because its implementation is backed by THashTable.
  325. // See hash_ut.cpp
  326. public:
  327. size_type size() const {
  328. return rep.size();
  329. }
  330. size_type max_size() const {
  331. return rep.max_size();
  332. }
  333. Y_PURE_FUNCTION bool empty() const {
  334. return rep.empty();
  335. }
  336. explicit operator bool() const noexcept {
  337. return !empty();
  338. }
  339. void swap(THashMultiSet& hs) {
  340. rep.swap(hs.rep);
  341. }
  342. iterator begin() const {
  343. return rep.begin();
  344. }
  345. iterator end() const {
  346. return rep.end();
  347. }
  348. iterator cbegin() const {
  349. return rep.begin();
  350. }
  351. iterator cend() const {
  352. return rep.end();
  353. }
  354. public:
  355. iterator insert(const value_type& obj) {
  356. return rep.insert_equal(obj);
  357. }
  358. template <typename... Args>
  359. iterator emplace(Args&&... args) {
  360. return rep.emplace_equal(std::forward<Args>(args)...);
  361. }
  362. template <class InputIterator>
  363. void insert(InputIterator f, InputIterator l) {
  364. rep.insert_equal(f, l);
  365. }
  366. iterator insert_noresize(const value_type& obj) {
  367. return rep.insert_equal_noresize(obj);
  368. }
  369. template <class TKey>
  370. iterator find(const TKey& key) const {
  371. return rep.find(key);
  372. }
  373. template <class TKey>
  374. size_type count(const TKey& key) const {
  375. return rep.count(key);
  376. }
  377. template <class TKey>
  378. std::pair<iterator, iterator> equal_range(const TKey& key) const {
  379. return rep.equal_range(key);
  380. }
  381. size_type erase(const key_type& key) {
  382. return rep.erase(key);
  383. }
  384. void erase(iterator it) {
  385. rep.erase(it);
  386. }
  387. void erase(iterator f, iterator l) {
  388. rep.erase(f, l);
  389. }
  390. void clear() {
  391. rep.clear();
  392. }
  393. void clear(size_t downsize_hint) {
  394. rep.clear(downsize_hint);
  395. }
  396. void basic_clear() {
  397. rep.basic_clear();
  398. }
  399. void release_nodes() {
  400. rep.release_nodes();
  401. }
  402. public:
  403. void reserve(size_type hint) {
  404. rep.reserve(hint);
  405. }
  406. size_type bucket_count() const {
  407. return rep.bucket_count();
  408. }
  409. size_type bucket_size(size_type n) const {
  410. return rep.bucket_size(n);
  411. }
  412. node_allocator_type& GetNodeAllocator() {
  413. return rep.GetNodeAllocator();
  414. }
  415. };
  416. template <class Val, class HashFcn, class EqualKey, class Alloc>
  417. inline bool operator==(const THashMultiSet<Val, HashFcn, EqualKey, Alloc>& hs1, const THashMultiSet<Val, HashFcn, EqualKey, Alloc>& hs2) {
  418. if (hs1.size() != hs2.size()) {
  419. return false;
  420. }
  421. EqualKey equalKey;
  422. auto it = hs1.begin();
  423. while (it != hs1.end()) {
  424. const auto& value = *it;
  425. size_t count = 0;
  426. for (; (it != hs1.end()) && (equalKey(*it, value)); ++it, ++count) {
  427. }
  428. if (hs2.count(value) != count) {
  429. return false;
  430. }
  431. }
  432. return true;
  433. }
  434. template <class Val, class HashFcn, class EqualKey, class Alloc>
  435. inline bool operator!=(const THashMultiSet<Val, HashFcn, EqualKey, Alloc>& hs1, const THashMultiSet<Val, HashFcn, EqualKey, Alloc>& hs2) {
  436. return !(hs1 == hs2);
  437. }