hash_set.h 14 KB

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