set.hpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. /*************************************************************************
  2. *
  3. * Copyright 2020 Realm Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. **************************************************************************/
  18. #ifndef REALM_SET_HPP
  19. #define REALM_SET_HPP
  20. #include <realm/collection.hpp>
  21. #include <realm/bplustree.hpp>
  22. #include <realm/array_key.hpp>
  23. #include <numeric> // std::iota
  24. namespace realm {
  25. class SetBase : public CollectionBase {
  26. public:
  27. using CollectionBase::CollectionBase;
  28. virtual ~SetBase() {}
  29. virtual SetBasePtr clone() const = 0;
  30. virtual std::pair<size_t, bool> insert_null() = 0;
  31. virtual std::pair<size_t, bool> erase_null() = 0;
  32. virtual std::pair<size_t, bool> insert_any(Mixed value) = 0;
  33. virtual std::pair<size_t, bool> erase_any(Mixed value) = 0;
  34. protected:
  35. void insert_repl(Replication* repl, size_t index, Mixed value) const;
  36. void erase_repl(Replication* repl, size_t index, Mixed value) const;
  37. void clear_repl(Replication* repl) const;
  38. };
  39. template <class T>
  40. class Set final : public CollectionBaseImpl<SetBase> {
  41. public:
  42. using Base = CollectionBaseImpl<SetBase>;
  43. using value_type = T;
  44. using iterator = CollectionIterator<Set<T>>;
  45. Set() = default;
  46. Set(const Obj& owner, ColKey col_key);
  47. Set(const Set& other);
  48. Set(Set&& other) noexcept;
  49. Set& operator=(const Set& other);
  50. Set& operator=(Set&& other) noexcept;
  51. using Base::operator==;
  52. using Base::operator!=;
  53. SetBasePtr clone() const final
  54. {
  55. return std::make_unique<Set<T>>(*this);
  56. }
  57. T get(size_t ndx) const
  58. {
  59. const auto current_size = size();
  60. if (ndx >= current_size) {
  61. throw std::out_of_range("Index out of range");
  62. }
  63. return m_tree->get(ndx);
  64. }
  65. iterator begin() const noexcept
  66. {
  67. return iterator{this, 0};
  68. }
  69. iterator end() const noexcept
  70. {
  71. return iterator{this, size()};
  72. }
  73. size_t find_first(const T& value) const
  74. {
  75. return find(value);
  76. }
  77. template <class Func>
  78. void find_all(T value, Func&& func) const
  79. {
  80. size_t found = find(value);
  81. if (found != not_found) {
  82. func(found);
  83. }
  84. }
  85. template <class Rhs>
  86. bool is_subset_of(const Rhs&) const;
  87. template <class It1, class It2>
  88. bool is_subset_of(It1, It2) const;
  89. template <class Rhs>
  90. bool is_strict_subset_of(const Rhs&) const;
  91. template <class It1, class It2>
  92. bool is_strict_subset_of(It1, It2) const;
  93. template <class Rhs>
  94. bool is_superset_of(const Rhs&) const;
  95. template <class It1, class It2>
  96. bool is_superset_of(It1, It2) const;
  97. template <class Rhs>
  98. bool is_strict_superset_of(const Rhs&) const;
  99. template <class It1, class It2>
  100. bool is_strict_superset_of(It1, It2) const;
  101. template <class Rhs>
  102. bool intersects(const Rhs&) const;
  103. template <class It1, class It2>
  104. bool intersects(It1, It2) const;
  105. template <class Rhs>
  106. bool set_equals(const Rhs&) const;
  107. template <class It1, class It2>
  108. bool set_equals(It1, It2) const;
  109. template <class Rhs>
  110. void assign_union(const Rhs&);
  111. template <class It1, class It2>
  112. void assign_union(It1, It2);
  113. template <class Rhs>
  114. void assign_intersection(const Rhs&);
  115. template <class It1, class It2>
  116. void assign_intersection(It1, It2);
  117. template <class Rhs>
  118. void assign_difference(const Rhs&);
  119. template <class It1, class It2>
  120. void assign_difference(It1, It2);
  121. template <class Rhs>
  122. void assign_symmetric_difference(const Rhs&);
  123. template <class It1, class It2>
  124. void assign_symmetric_difference(It1, It2);
  125. /// Insert a value into the set if it does not already exist, returning the index of the inserted value,
  126. /// or the index of the already-existing value.
  127. std::pair<size_t, bool> insert(T value);
  128. /// Find the index of a value in the set, or `size_t(-1)` if it is not in the set.
  129. size_t find(T value) const;
  130. /// Erase an element from the set, returning true if the set contained the element.
  131. std::pair<size_t, bool> erase(T value);
  132. // Overriding members of CollectionBase:
  133. size_t size() const final;
  134. bool is_null(size_t ndx) const final;
  135. Mixed get_any(size_t ndx) const final
  136. {
  137. return get(ndx);
  138. }
  139. void clear() final;
  140. Mixed min(size_t* return_ndx = nullptr) const final;
  141. Mixed max(size_t* return_ndx = nullptr) const final;
  142. Mixed sum(size_t* return_cnt = nullptr) const final;
  143. Mixed avg(size_t* return_cnt = nullptr) const final;
  144. std::unique_ptr<CollectionBase> clone_collection() const final
  145. {
  146. return std::make_unique<Set<T>>(*this);
  147. }
  148. void sort(std::vector<size_t>& indices, bool ascending = true) const final;
  149. void distinct(std::vector<size_t>& indices, util::Optional<bool> sort_order = util::none) const final;
  150. // Overriding members of SetBase:
  151. size_t find_any(Mixed) const final;
  152. std::pair<size_t, bool> insert_null() final;
  153. std::pair<size_t, bool> erase_null() final;
  154. std::pair<size_t, bool> insert_any(Mixed value) final;
  155. std::pair<size_t, bool> erase_any(Mixed value) final;
  156. const BPlusTree<T>& get_tree() const
  157. {
  158. return *m_tree;
  159. }
  160. private:
  161. mutable std::unique_ptr<BPlusTree<T>> m_tree;
  162. using Base::m_col_key;
  163. using Base::m_obj;
  164. using Base::m_valid;
  165. void create()
  166. {
  167. m_tree->create();
  168. m_valid = true;
  169. }
  170. REALM_NOINLINE bool init_from_parent() const final
  171. {
  172. m_valid = m_tree->init_from_parent();
  173. update_content_version();
  174. return m_valid;
  175. }
  176. REALM_NOINLINE void ensure_created()
  177. {
  178. if (!m_valid && m_obj.is_valid()) {
  179. create();
  180. }
  181. }
  182. void do_insert(size_t ndx, T value);
  183. void do_erase(size_t ndx);
  184. iterator find_impl(const T& value) const;
  185. friend class LnkSet;
  186. };
  187. class LnkSet final : public ObjCollectionBase<SetBase> {
  188. public:
  189. using Base = ObjCollectionBase<SetBase>;
  190. using value_type = ObjKey;
  191. using iterator = CollectionIterator<LnkSet>;
  192. LnkSet() = default;
  193. LnkSet(const Obj& owner, ColKey col_key)
  194. : m_set(owner, col_key)
  195. {
  196. update_unresolved();
  197. }
  198. LnkSet(const LnkSet&) = default;
  199. LnkSet(LnkSet&&) = default;
  200. LnkSet& operator=(const LnkSet&) = default;
  201. LnkSet& operator=(LnkSet&&) = default;
  202. bool operator==(const LnkSet& other) const;
  203. bool operator!=(const LnkSet& other) const;
  204. ObjKey get(size_t ndx) const;
  205. size_t find(ObjKey) const;
  206. size_t find_first(ObjKey) const;
  207. std::pair<size_t, bool> insert(ObjKey);
  208. std::pair<size_t, bool> erase(ObjKey);
  209. template <class Rhs>
  210. void assign_union(const Rhs&);
  211. template <class It1, class It2>
  212. void assign_union(It1, It2);
  213. template <class Rhs>
  214. void assign_intersection(const Rhs&);
  215. template <class It1, class It2>
  216. void assign_intersection(It1, It2);
  217. template <class Rhs>
  218. void assign_difference(const Rhs&);
  219. template <class It1, class It2>
  220. void assign_difference(It1, It2);
  221. template <class Rhs>
  222. void assign_symmetric_difference(const Rhs&);
  223. template <class It1, class It2>
  224. void assign_symmetric_difference(It1, It2);
  225. bool is_subset_of(const LnkSet& rhs) const;
  226. bool is_strict_subset_of(const LnkSet& rhs) const;
  227. bool is_superset_of(const LnkSet& rhs) const;
  228. bool is_strict_superset_of(const LnkSet& rhs) const;
  229. bool intersects(const LnkSet& rhs) const;
  230. // Overriding members of CollectionBase:
  231. using CollectionBase::get_key;
  232. CollectionBasePtr clone_collection() const
  233. {
  234. return clone_linkset();
  235. }
  236. size_t size() const final;
  237. bool is_null(size_t ndx) const final;
  238. Mixed get_any(size_t ndx) const final;
  239. void clear() final;
  240. Mixed min(size_t* return_ndx = nullptr) const final;
  241. Mixed max(size_t* return_ndx = nullptr) const final;
  242. Mixed sum(size_t* return_cnt = nullptr) const final;
  243. Mixed avg(size_t* return_cnt = nullptr) const final;
  244. void sort(std::vector<size_t>& indices, bool ascending = true) const final;
  245. void distinct(std::vector<size_t>& indices, util::Optional<bool> sort_order = util::none) const final;
  246. const Obj& get_obj() const noexcept final;
  247. bool is_attached() const final;
  248. bool has_changed() const final;
  249. ColKey get_col_key() const noexcept final;
  250. // Overriding members of SetBase:
  251. SetBasePtr clone() const
  252. {
  253. return clone_linkset();
  254. }
  255. size_t find_any(Mixed) const final;
  256. std::pair<size_t, bool> insert_null() final;
  257. std::pair<size_t, bool> erase_null() final;
  258. std::pair<size_t, bool> insert_any(Mixed value) final;
  259. std::pair<size_t, bool> erase_any(Mixed value) final;
  260. // Overriding members of ObjList:
  261. bool is_obj_valid(size_t) const noexcept final;
  262. Obj get_object(size_t ndx) const final;
  263. ObjKey get_key(size_t ndx) const final;
  264. // LnkSet interface:
  265. std::unique_ptr<LnkSet> clone_linkset() const
  266. {
  267. // FIXME: The copy constructor requires this.
  268. update_if_needed();
  269. return std::make_unique<LnkSet>(*this);
  270. }
  271. template <class Func>
  272. void find_all(ObjKey value, Func&& func) const
  273. {
  274. if (value.is_unresolved()) {
  275. return;
  276. }
  277. m_set.find_all(value, [&](size_t ndx) {
  278. func(real2virtual(ndx));
  279. });
  280. }
  281. TableView get_sorted_view(SortDescriptor order) const;
  282. TableView get_sorted_view(ColKey column_key, bool ascending = true);
  283. void remove_target_row(size_t link_ndx);
  284. void remove_all_target_rows();
  285. iterator begin() const noexcept
  286. {
  287. return iterator{this, 0};
  288. }
  289. iterator end() const noexcept
  290. {
  291. return iterator{this, size()};
  292. }
  293. private:
  294. Set<ObjKey> m_set;
  295. bool do_update_if_needed() const final
  296. {
  297. return m_set.update_if_needed();
  298. }
  299. bool do_init_from_parent() const final
  300. {
  301. return m_set.init_from_parent();
  302. }
  303. BPlusTree<ObjKey>& get_mutable_tree() const final
  304. {
  305. return *m_set.m_tree;
  306. }
  307. };
  308. template <>
  309. void Set<ObjKey>::do_insert(size_t, ObjKey);
  310. template <>
  311. void Set<ObjKey>::do_erase(size_t);
  312. template <>
  313. void Set<ObjLink>::do_insert(size_t, ObjLink);
  314. template <>
  315. void Set<ObjLink>::do_erase(size_t);
  316. template <>
  317. void Set<Mixed>::do_insert(size_t, Mixed);
  318. template <>
  319. void Set<Mixed>::do_erase(size_t);
  320. /// Compare set elements.
  321. ///
  322. /// We cannot use `std::less<>` directly, because the ordering of set elements
  323. /// impacts the file format. For primitive types this is trivial (and can indeed
  324. /// be just `std::less<>`), but for example `Mixed` has specialized comparison
  325. /// that defines equality of numeric types.
  326. template <class T>
  327. struct SetElementLessThan {
  328. bool operator()(const T& a, const T& b) const noexcept
  329. {
  330. // CAUTION: This routine is technically part of the file format, because
  331. // it determines the storage order of Set elements.
  332. return a < b;
  333. }
  334. };
  335. template <class T>
  336. struct SetElementEquals {
  337. bool operator()(const T& a, const T& b) const noexcept
  338. {
  339. // CAUTION: This routine is technically part of the file format, because
  340. // it determines the storage order of Set elements.
  341. return a == b;
  342. }
  343. };
  344. template <>
  345. struct SetElementLessThan<Mixed> {
  346. bool operator()(const Mixed& a, const Mixed& b) const noexcept
  347. {
  348. // CAUTION: This routine is technically part of the file format, because
  349. // it determines the storage order of Set elements.
  350. if (a.is_null() != b.is_null()) {
  351. // If a is NULL but not b, a < b.
  352. return a.is_null();
  353. }
  354. else if (a.is_null()) {
  355. // NULLs are equal.
  356. return false;
  357. }
  358. if (a.get_type() != b.get_type()) {
  359. return a.get_type() < b.get_type();
  360. }
  361. switch (a.get_type()) {
  362. case type_Int:
  363. return a.get<int64_t>() < b.get<int64_t>();
  364. case type_Bool:
  365. return a.get<bool>() < b.get<bool>();
  366. case type_String:
  367. return a.get<StringData>() < b.get<StringData>();
  368. case type_Binary:
  369. return a.get<BinaryData>() < b.get<BinaryData>();
  370. case type_Timestamp:
  371. return a.get<Timestamp>() < b.get<Timestamp>();
  372. case type_Float:
  373. return a.get<float>() < b.get<float>();
  374. case type_Double:
  375. return a.get<double>() < b.get<double>();
  376. case type_Decimal:
  377. return a.get<Decimal128>() < b.get<Decimal128>();
  378. case type_ObjectId:
  379. return a.get<ObjectId>() < b.get<ObjectId>();
  380. case type_UUID:
  381. return a.get<UUID>() < b.get<UUID>();
  382. case type_TypedLink:
  383. return a.get<ObjLink>() < b.get<ObjLink>();
  384. case type_Mixed:
  385. [[fallthrough]];
  386. case type_Link:
  387. [[fallthrough]];
  388. case type_LinkList:
  389. REALM_TERMINATE("Invalid Mixed payload in Set.");
  390. }
  391. return false;
  392. }
  393. };
  394. template <>
  395. struct SetElementEquals<Mixed> {
  396. bool operator()(const Mixed& a, const Mixed& b) const noexcept
  397. {
  398. // CAUTION: This routine is technically part of the file format, because
  399. // it determines the storage order of Set elements.
  400. if (a.is_null() != b.is_null()) {
  401. return false;
  402. }
  403. else if (a.is_null()) {
  404. return true;
  405. }
  406. if (a.get_type() != b.get_type()) {
  407. return false;
  408. }
  409. switch (a.get_type()) {
  410. case type_Int:
  411. return a.get<int64_t>() == b.get<int64_t>();
  412. case type_Bool:
  413. return a.get<bool>() == b.get<bool>();
  414. case type_String:
  415. return a.get<StringData>() == b.get<StringData>();
  416. case type_Binary:
  417. return a.get<BinaryData>() == b.get<BinaryData>();
  418. case type_Timestamp:
  419. return a.get<Timestamp>() == b.get<Timestamp>();
  420. case type_Float:
  421. return a.get<float>() == b.get<float>();
  422. case type_Double:
  423. return a.get<double>() == b.get<double>();
  424. case type_Decimal:
  425. return a.get<Decimal128>() == b.get<Decimal128>();
  426. case type_ObjectId:
  427. return a.get<ObjectId>() == b.get<ObjectId>();
  428. case type_UUID:
  429. return a.get<UUID>() == b.get<UUID>();
  430. case type_TypedLink:
  431. return a.get<ObjLink>() == b.get<ObjLink>();
  432. case type_Mixed:
  433. [[fallthrough]];
  434. case type_Link:
  435. [[fallthrough]];
  436. case type_LinkList:
  437. REALM_TERMINATE("Invalid Mixed payload in Set.");
  438. }
  439. return false;
  440. }
  441. };
  442. template <class T>
  443. inline Set<T>::Set(const Obj& obj, ColKey col_key)
  444. : Base(obj, col_key)
  445. , m_tree(new BPlusTree<value_type>(obj.get_alloc()))
  446. {
  447. if (!col_key.is_set()) {
  448. throw LogicError(LogicError::collection_type_mismatch);
  449. }
  450. check_column_type<value_type>(m_col_key);
  451. m_tree->set_parent(this, 0); // ndx not used, implicit in m_owner
  452. if (m_obj) {
  453. // Fine because init_from_parent() is final.
  454. this->init_from_parent();
  455. }
  456. }
  457. template <class T>
  458. inline Set<T>::Set(const Set& other)
  459. : Base(static_cast<const Base&>(other))
  460. {
  461. // FIXME: If the other side needed an update, we could be using a stale ref
  462. // below.
  463. REALM_ASSERT(!other.update_if_needed());
  464. if (other.m_tree) {
  465. Allocator& alloc = other.m_tree->get_alloc();
  466. m_tree = std::make_unique<BPlusTree<T>>(alloc);
  467. m_tree->set_parent(this, 0);
  468. if (m_valid)
  469. m_tree->init_from_ref(other.m_tree->get_ref());
  470. }
  471. }
  472. template <class T>
  473. inline Set<T>::Set(Set&& other) noexcept
  474. : Base(static_cast<Base&&>(other))
  475. , m_tree(std::exchange(other.m_tree, nullptr))
  476. {
  477. if (m_tree) {
  478. m_tree->set_parent(this, 0);
  479. }
  480. }
  481. template <class T>
  482. inline Set<T>& Set<T>::operator=(const Set& other)
  483. {
  484. Base::operator=(static_cast<const Base&>(other));
  485. if (this != &other) {
  486. m_tree.reset();
  487. if (other.m_tree) {
  488. Allocator& alloc = other.m_tree->get_alloc();
  489. m_tree = std::make_unique<BPlusTree<T>>(alloc);
  490. m_tree->set_parent(this, 0);
  491. if (m_valid) {
  492. m_tree->init_from_ref(other.m_tree->get_ref());
  493. }
  494. }
  495. }
  496. return *this;
  497. }
  498. template <class T>
  499. inline Set<T>& Set<T>::operator=(Set&& other) noexcept
  500. {
  501. Base::operator=(static_cast<Base&&>(other));
  502. if (this != &other) {
  503. m_tree = std::exchange(other.m_tree, nullptr);
  504. if (m_tree) {
  505. m_tree->set_parent(this, 0);
  506. }
  507. }
  508. return *this;
  509. }
  510. template <typename U>
  511. Set<U> Obj::get_set(ColKey col_key) const
  512. {
  513. return Set<U>(*this, col_key);
  514. }
  515. inline LnkSet Obj::get_linkset(ColKey col_key) const
  516. {
  517. return LnkSet{*this, col_key};
  518. }
  519. inline LnkSetPtr Obj::get_linkset_ptr(ColKey col_key) const
  520. {
  521. return std::make_unique<LnkSet>(*this, col_key);
  522. }
  523. template <class T>
  524. size_t Set<T>::find(T value) const
  525. {
  526. auto it = find_impl(value);
  527. if (it != end() && SetElementEquals<T>{}(*it, value)) {
  528. return it.index();
  529. }
  530. return npos;
  531. }
  532. template <class T>
  533. size_t Set<T>::find_any(Mixed value) const
  534. {
  535. if constexpr (std::is_same_v<T, Mixed>) {
  536. return find(value);
  537. }
  538. else {
  539. if (value.is_null()) {
  540. if (!m_nullable) {
  541. return not_found;
  542. }
  543. return find(BPlusTree<T>::default_value(true));
  544. }
  545. else {
  546. return find(value.get<typename util::RemoveOptional<T>::type>());
  547. }
  548. }
  549. }
  550. template <class T>
  551. REALM_NOINLINE auto Set<T>::find_impl(const T& value) const -> iterator
  552. {
  553. auto b = this->begin();
  554. auto e = this->end();
  555. return std::lower_bound(b, e, value, SetElementLessThan<T>{});
  556. }
  557. template <class T>
  558. std::pair<size_t, bool> Set<T>::insert(T value)
  559. {
  560. update_if_needed();
  561. ensure_created();
  562. this->ensure_writeable();
  563. auto it = find_impl(value);
  564. if (it != this->end() && SetElementEquals<T>{}(*it, value)) {
  565. return {it.index(), false};
  566. }
  567. if (Replication* repl = m_obj.get_replication()) {
  568. // FIXME: We should emit an instruction regardless of element presence for the purposes of conflict
  569. // resolution in synchronized databases. The reason is that the new insertion may come at a later time
  570. // than an interleaving erase instruction, so emitting the instruction ensures that last "write" wins.
  571. this->insert_repl(repl, it.index(), value);
  572. }
  573. do_insert(it.index(), value);
  574. bump_content_version();
  575. return {it.index(), true};
  576. }
  577. template <class T>
  578. std::pair<size_t, bool> Set<T>::insert_any(Mixed value)
  579. {
  580. if constexpr (std::is_same_v<T, Mixed>) {
  581. return insert(value);
  582. }
  583. else {
  584. if (value.is_null()) {
  585. return insert_null();
  586. }
  587. else {
  588. return insert(value.get<typename util::RemoveOptional<T>::type>());
  589. }
  590. }
  591. }
  592. template <class T>
  593. std::pair<size_t, bool> Set<T>::erase(T value)
  594. {
  595. update_if_needed();
  596. this->ensure_writeable();
  597. auto it = find_impl(value);
  598. if (it == end() || !SetElementEquals<T>{}(*it, value)) {
  599. return {npos, false};
  600. }
  601. if (Replication* repl = m_obj.get_replication()) {
  602. this->erase_repl(repl, it.index(), value);
  603. }
  604. do_erase(it.index());
  605. bump_content_version();
  606. return {it.index(), true};
  607. }
  608. template <class T>
  609. std::pair<size_t, bool> Set<T>::erase_any(Mixed value)
  610. {
  611. if constexpr (std::is_same_v<T, Mixed>) {
  612. return erase(value);
  613. }
  614. else {
  615. if (value.is_null()) {
  616. return erase_null();
  617. }
  618. else {
  619. return erase(value.get<typename util::RemoveOptional<T>::type>());
  620. }
  621. }
  622. }
  623. template <class T>
  624. inline std::pair<size_t, bool> Set<T>::insert_null()
  625. {
  626. return insert(BPlusTree<T>::default_value(this->m_nullable));
  627. }
  628. template <class T>
  629. std::pair<size_t, bool> Set<T>::erase_null()
  630. {
  631. return erase(BPlusTree<T>::default_value(this->m_nullable));
  632. }
  633. template <class T>
  634. REALM_NOINLINE size_t Set<T>::size() const
  635. {
  636. if (!is_attached())
  637. return 0;
  638. update_if_needed();
  639. if (!m_valid) {
  640. return 0;
  641. }
  642. return m_tree->size();
  643. }
  644. template <class T>
  645. inline bool Set<T>::is_null(size_t ndx) const
  646. {
  647. return m_nullable && value_is_null(get(ndx));
  648. }
  649. template <class T>
  650. inline void Set<T>::clear()
  651. {
  652. ensure_created();
  653. update_if_needed();
  654. this->ensure_writeable();
  655. if (size() > 0) {
  656. if (Replication* repl = this->m_obj.get_replication()) {
  657. this->clear_repl(repl);
  658. }
  659. m_tree->clear();
  660. bump_content_version();
  661. // For Set<ObjKey>, we are sure that there are no longer any unresolved
  662. // links.
  663. m_tree->set_context_flag(false);
  664. }
  665. }
  666. template <class T>
  667. inline Mixed Set<T>::min(size_t* return_ndx) const
  668. {
  669. update_if_needed();
  670. return MinHelper<T>::eval(*m_tree, return_ndx);
  671. }
  672. template <class T>
  673. inline Mixed Set<T>::max(size_t* return_ndx) const
  674. {
  675. update_if_needed();
  676. return MaxHelper<T>::eval(*m_tree, return_ndx);
  677. }
  678. template <class T>
  679. inline Mixed Set<T>::sum(size_t* return_cnt) const
  680. {
  681. update_if_needed();
  682. return SumHelper<T>::eval(*m_tree, return_cnt);
  683. }
  684. template <class T>
  685. inline Mixed Set<T>::avg(size_t* return_cnt) const
  686. {
  687. update_if_needed();
  688. return AverageHelper<T>::eval(*m_tree, return_cnt);
  689. }
  690. void set_sorted_indices(size_t sz, std::vector<size_t>& indices, bool ascending);
  691. template <class T>
  692. inline void Set<T>::sort(std::vector<size_t>& indices, bool ascending) const
  693. {
  694. auto sz = size();
  695. set_sorted_indices(sz, indices, ascending);
  696. }
  697. template <class T>
  698. inline void Set<T>::distinct(std::vector<size_t>& indices, util::Optional<bool> sort_order) const
  699. {
  700. auto ascending = !sort_order || *sort_order;
  701. sort(indices, ascending);
  702. }
  703. template <class T>
  704. void Set<T>::do_insert(size_t ndx, T value)
  705. {
  706. m_tree->insert(ndx, value);
  707. }
  708. template <class T>
  709. void Set<T>::do_erase(size_t ndx)
  710. {
  711. m_tree->erase(ndx);
  712. }
  713. template <class T>
  714. template <class Rhs>
  715. bool Set<T>::is_subset_of(const Rhs& rhs) const
  716. {
  717. return is_subset_of(std::begin(rhs), std::end(rhs));
  718. }
  719. template <class T>
  720. template <class It1, class It2>
  721. bool Set<T>::is_subset_of(It1 first, It2 last) const
  722. {
  723. return std::includes(first, last, begin(), end(), SetElementLessThan<T>{});
  724. }
  725. template <class T>
  726. template <class Rhs>
  727. bool Set<T>::is_strict_subset_of(const Rhs& rhs) const
  728. {
  729. if constexpr (std::is_same_v<Rhs, Set<T>>) {
  730. return size() != rhs.size() && is_subset_of(rhs);
  731. }
  732. else {
  733. return is_strict_subset_of(rhs.begin(), rhs.end());
  734. }
  735. }
  736. template <class T>
  737. template <class It1, class It2>
  738. bool Set<T>::is_strict_subset_of(It1 begin, It2 end) const
  739. {
  740. if (size_t(std::distance(begin, end)) == size())
  741. return false;
  742. return is_subset_of(begin, end);
  743. }
  744. template <class T>
  745. template <class Rhs>
  746. bool Set<T>::is_superset_of(const Rhs& rhs) const
  747. {
  748. return is_superset_of(std::begin(rhs), std::end(rhs));
  749. }
  750. template <class T>
  751. template <class It1, class It2>
  752. bool Set<T>::is_superset_of(It1 first, It2 last) const
  753. {
  754. return std::includes(begin(), end(), first, last, SetElementLessThan<T>{});
  755. }
  756. template <class T>
  757. template <class Rhs>
  758. bool Set<T>::is_strict_superset_of(const Rhs& rhs) const
  759. {
  760. if constexpr (std::is_same_v<Rhs, Set<T>>) {
  761. return size() != rhs.size() && is_superset_of(rhs);
  762. }
  763. else {
  764. return is_strict_superset_of(rhs.begin(), rhs.end());
  765. }
  766. }
  767. template <class T>
  768. template <class It1, class It2>
  769. bool Set<T>::is_strict_superset_of(It1 begin, It2 end) const
  770. {
  771. if (size_t(std::distance(begin, end)) == size())
  772. return false;
  773. return is_superset_of(begin, end);
  774. }
  775. template <class T>
  776. template <class Rhs>
  777. bool Set<T>::intersects(const Rhs& rhs) const
  778. {
  779. return intersects(std::begin(rhs), std::end(rhs));
  780. }
  781. template <class T>
  782. template <class It1, class It2>
  783. bool Set<T>::intersects(It1 first, It2 last) const
  784. {
  785. SetElementLessThan<T> less;
  786. auto it = begin();
  787. while (it != end() && first != last) {
  788. if (less(*it, *first)) {
  789. ++it;
  790. }
  791. else if (less(*first, *it)) {
  792. ++first;
  793. }
  794. else {
  795. return true;
  796. }
  797. }
  798. return false;
  799. }
  800. template <class T>
  801. template <class Rhs>
  802. bool Set<T>::set_equals(const Rhs& rhs) const
  803. {
  804. if (size() != rhs.size())
  805. return false;
  806. return set_equals(rhs.begin(), rhs.end());
  807. }
  808. template <class T>
  809. template <class It1, class It2>
  810. bool Set<T>::set_equals(It1 begin2, It2 end2) const
  811. {
  812. auto end1 = end();
  813. auto it1 = begin();
  814. auto it2 = begin2;
  815. auto cmp = SetElementEquals<T>{};
  816. for (; it1 != end1 && it2 != end2; ++it1, ++it2) {
  817. if (!cmp(*it1, *it2)) {
  818. return false;
  819. }
  820. }
  821. return it1 == end1 && it2 == end2;
  822. }
  823. template <class T>
  824. template <class Rhs>
  825. inline void Set<T>::assign_union(const Rhs& rhs)
  826. {
  827. assign_union(std::begin(rhs), std::end(rhs));
  828. }
  829. template <class T>
  830. template <class It1, class It2>
  831. void Set<T>::assign_union(It1 first, It2 last)
  832. {
  833. std::vector<T> the_diff;
  834. std::set_difference(first, last, begin(), end(), std::back_inserter(the_diff), SetElementLessThan<T>{});
  835. // 'the_diff' now contains all the elements that are in foreign set, but not in 'this'
  836. // Now insert those elements
  837. for (auto value : the_diff) {
  838. insert(value);
  839. }
  840. }
  841. template <class T>
  842. template <class Rhs>
  843. inline void Set<T>::assign_intersection(const Rhs& rhs)
  844. {
  845. assign_intersection(std::begin(rhs), std::end(rhs));
  846. }
  847. template <class T>
  848. template <class It1, class It2>
  849. void Set<T>::assign_intersection(It1 first, It2 last)
  850. {
  851. std::vector<T> intersection;
  852. std::set_intersection(first, last, begin(), end(), std::back_inserter(intersection), SetElementLessThan<T>{});
  853. clear();
  854. // Elements in intersection comes from foreign set, so ok to use here
  855. for (auto value : intersection) {
  856. insert(value);
  857. }
  858. }
  859. template <class T>
  860. template <class Rhs>
  861. inline void Set<T>::assign_difference(const Rhs& rhs)
  862. {
  863. assign_difference(std::begin(rhs), std::end(rhs));
  864. }
  865. template <class T>
  866. template <class It1, class It2>
  867. void Set<T>::assign_difference(It1 first, It2 last)
  868. {
  869. std::vector<T> intersection;
  870. std::set_intersection(first, last, begin(), end(), std::back_inserter(intersection), SetElementLessThan<T>{});
  871. // 'intersection' now contains all the elements that are in both foreign set and 'this'.
  872. // Remove those elements. The elements comes from the foreign set, so ok to refer to.
  873. for (auto value : intersection) {
  874. erase(value);
  875. }
  876. }
  877. template <class T>
  878. template <class Rhs>
  879. inline void Set<T>::assign_symmetric_difference(const Rhs& rhs)
  880. {
  881. assign_symmetric_difference(std::begin(rhs), std::end(rhs));
  882. }
  883. template <class T>
  884. template <class It1, class It2>
  885. void Set<T>::assign_symmetric_difference(It1 first, It2 last)
  886. {
  887. std::vector<T> difference;
  888. std::set_difference(first, last, begin(), end(), std::back_inserter(difference), SetElementLessThan<T>{});
  889. std::vector<T> intersection;
  890. std::set_intersection(first, last, begin(), end(), std::back_inserter(intersection), SetElementLessThan<T>{});
  891. // Now remove the common elements and add the differences
  892. for (auto value : intersection) {
  893. erase(value);
  894. }
  895. for (auto value : difference) {
  896. insert(value);
  897. }
  898. }
  899. inline bool LnkSet::operator==(const LnkSet& other) const
  900. {
  901. return m_set == other.m_set;
  902. }
  903. inline bool LnkSet::operator!=(const LnkSet& other) const
  904. {
  905. return m_set != other.m_set;
  906. }
  907. inline ObjKey LnkSet::get(size_t ndx) const
  908. {
  909. update_if_needed();
  910. return m_set.get(virtual2real(ndx));
  911. }
  912. inline size_t LnkSet::find(ObjKey value) const
  913. {
  914. update_if_needed();
  915. if (value.is_unresolved()) {
  916. return not_found;
  917. }
  918. size_t ndx = m_set.find(value);
  919. if (ndx == not_found) {
  920. return not_found;
  921. }
  922. return real2virtual(ndx);
  923. }
  924. inline size_t LnkSet::find_first(ObjKey value) const
  925. {
  926. return find(value);
  927. }
  928. inline size_t LnkSet::size() const
  929. {
  930. update_if_needed();
  931. return m_set.size() - num_unresolved();
  932. }
  933. inline std::pair<size_t, bool> LnkSet::insert(ObjKey value)
  934. {
  935. REALM_ASSERT(!value.is_unresolved());
  936. update_if_needed();
  937. auto [ndx, inserted] = m_set.insert(value);
  938. return {real2virtual(ndx), inserted};
  939. }
  940. inline std::pair<size_t, bool> LnkSet::erase(ObjKey value)
  941. {
  942. REALM_ASSERT(!value.is_unresolved());
  943. update_if_needed();
  944. auto [ndx, removed] = m_set.erase(value);
  945. if (removed) {
  946. ndx = real2virtual(ndx);
  947. }
  948. return {ndx, removed};
  949. }
  950. inline bool LnkSet::is_null(size_t ndx) const
  951. {
  952. update_if_needed();
  953. return m_set.is_null(virtual2real(ndx));
  954. }
  955. inline Mixed LnkSet::get_any(size_t ndx) const
  956. {
  957. update_if_needed();
  958. return m_set.get_any(virtual2real(ndx));
  959. }
  960. inline std::pair<size_t, bool> LnkSet::insert_null()
  961. {
  962. update_if_needed();
  963. auto [ndx, inserted] = m_set.insert_null();
  964. return {real2virtual(ndx), inserted};
  965. }
  966. inline std::pair<size_t, bool> LnkSet::erase_null()
  967. {
  968. update_if_needed();
  969. auto [ndx, erased] = m_set.erase_null();
  970. if (erased) {
  971. ndx = real2virtual(ndx);
  972. }
  973. return {ndx, erased};
  974. }
  975. inline std::pair<size_t, bool> LnkSet::insert_any(Mixed value)
  976. {
  977. update_if_needed();
  978. auto [ndx, inserted] = m_set.insert_any(value);
  979. return {real2virtual(ndx), inserted};
  980. }
  981. inline std::pair<size_t, bool> LnkSet::erase_any(Mixed value)
  982. {
  983. auto [ndx, erased] = m_set.erase_any(value);
  984. if (erased) {
  985. ndx = real2virtual(ndx);
  986. }
  987. return {ndx, erased};
  988. }
  989. inline void LnkSet::clear()
  990. {
  991. m_set.clear();
  992. clear_unresolved();
  993. }
  994. inline Mixed LnkSet::min(size_t* return_ndx) const
  995. {
  996. size_t found = not_found;
  997. auto value = m_set.min(&found);
  998. if (found != not_found && return_ndx) {
  999. *return_ndx = real2virtual(found);
  1000. }
  1001. return value;
  1002. }
  1003. inline Mixed LnkSet::max(size_t* return_ndx) const
  1004. {
  1005. size_t found = not_found;
  1006. auto value = m_set.max(&found);
  1007. if (found != not_found && return_ndx) {
  1008. *return_ndx = real2virtual(found);
  1009. }
  1010. return value;
  1011. }
  1012. inline Mixed LnkSet::sum(size_t* return_cnt) const
  1013. {
  1014. static_cast<void>(return_cnt);
  1015. REALM_TERMINATE("Not implemented");
  1016. }
  1017. inline Mixed LnkSet::avg(size_t* return_cnt) const
  1018. {
  1019. static_cast<void>(return_cnt);
  1020. REALM_TERMINATE("Not implemented");
  1021. }
  1022. inline void LnkSet::sort(std::vector<size_t>& indices, bool ascending) const
  1023. {
  1024. update_if_needed();
  1025. // Map the input indices to real indices.
  1026. std::transform(indices.begin(), indices.end(), indices.begin(), [this](size_t ndx) {
  1027. return virtual2real(ndx);
  1028. });
  1029. m_set.sort(indices, ascending);
  1030. // Map the output indices to virtual indices.
  1031. std::transform(indices.begin(), indices.end(), indices.begin(), [this](size_t ndx) {
  1032. return real2virtual(ndx);
  1033. });
  1034. }
  1035. inline void LnkSet::distinct(std::vector<size_t>& indices, util::Optional<bool> sort_order) const
  1036. {
  1037. update_if_needed();
  1038. // Map the input indices to real indices.
  1039. std::transform(indices.begin(), indices.end(), indices.begin(), [this](size_t ndx) {
  1040. return virtual2real(ndx);
  1041. });
  1042. m_set.distinct(indices, sort_order);
  1043. // Map the output indices to virtual indices.
  1044. std::transform(indices.begin(), indices.end(), indices.begin(), [this](size_t ndx) {
  1045. return real2virtual(ndx);
  1046. });
  1047. }
  1048. inline const Obj& LnkSet::get_obj() const noexcept
  1049. {
  1050. return m_set.get_obj();
  1051. }
  1052. inline bool LnkSet::is_attached() const
  1053. {
  1054. return m_set.is_attached();
  1055. }
  1056. inline bool LnkSet::has_changed() const
  1057. {
  1058. return m_set.has_changed();
  1059. }
  1060. inline ColKey LnkSet::get_col_key() const noexcept
  1061. {
  1062. return m_set.get_col_key();
  1063. }
  1064. inline size_t LnkSet::find_any(Mixed value) const
  1065. {
  1066. if (value.is_null())
  1067. return not_found;
  1068. if (value.get_type() != type_Link)
  1069. return not_found;
  1070. size_t found = find(value.get<ObjKey>());
  1071. if (found != not_found) {
  1072. found = real2virtual(found);
  1073. }
  1074. return found;
  1075. }
  1076. inline bool LnkSet::is_obj_valid(size_t) const noexcept
  1077. {
  1078. // LnkSet cannot contain NULL links.
  1079. return true;
  1080. }
  1081. inline Obj LnkSet::get_object(size_t ndx) const
  1082. {
  1083. ObjKey key = get(ndx);
  1084. return get_target_table()->get_object(key);
  1085. }
  1086. inline ObjKey LnkSet::get_key(size_t ndx) const
  1087. {
  1088. return get(ndx);
  1089. }
  1090. template <class Rhs>
  1091. inline void LnkSet::assign_union(const Rhs& rhs)
  1092. {
  1093. assign_union(std::begin(rhs), std::end(rhs));
  1094. }
  1095. template <class It1, class It2>
  1096. inline void LnkSet::assign_union(It1 first, It2 last)
  1097. {
  1098. m_set.assign_union(first, last);
  1099. update_unresolved();
  1100. }
  1101. template <class Rhs>
  1102. inline void LnkSet::assign_intersection(const Rhs& rhs)
  1103. {
  1104. assign_intersection(std::begin(rhs), std::end(rhs));
  1105. }
  1106. template <class It1, class It2>
  1107. inline void LnkSet::assign_intersection(It1 first, It2 last)
  1108. {
  1109. m_set.assign_intersection(first, last);
  1110. update_unresolved();
  1111. }
  1112. template <class Rhs>
  1113. inline void LnkSet::assign_difference(const Rhs& rhs)
  1114. {
  1115. assign_difference(std::begin(rhs), std::end(rhs));
  1116. }
  1117. template <class It1, class It2>
  1118. inline void LnkSet::assign_difference(It1 first, It2 last)
  1119. {
  1120. m_set.assign_difference(first, last);
  1121. update_unresolved();
  1122. }
  1123. template <class Rhs>
  1124. inline void LnkSet::assign_symmetric_difference(const Rhs& rhs)
  1125. {
  1126. assign_symmetric_difference(std::begin(rhs), std::end(rhs));
  1127. }
  1128. template <class It1, class It2>
  1129. inline void LnkSet::assign_symmetric_difference(It1 first, It2 last)
  1130. {
  1131. m_set.assign_symmetric_difference(first, last);
  1132. update_unresolved();
  1133. }
  1134. } // namespace realm
  1135. #endif // REALM_SET_HPP