keys.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*************************************************************************
  2. *
  3. * Copyright 2016 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_KEYS_HPP
  19. #define REALM_KEYS_HPP
  20. #include <realm/util/to_string.hpp>
  21. #include <realm/column_type.hpp>
  22. #include <ostream>
  23. #include <vector>
  24. namespace realm {
  25. class Obj;
  26. struct TableKey {
  27. static constexpr uint32_t null_value = uint32_t(-1) >> 1; // free top bit
  28. constexpr TableKey() noexcept
  29. : value(null_value)
  30. {
  31. }
  32. explicit TableKey(uint32_t val) noexcept
  33. : value(val)
  34. {
  35. }
  36. TableKey& operator=(uint32_t val) noexcept
  37. {
  38. value = val;
  39. return *this;
  40. }
  41. bool operator==(const TableKey& rhs) const noexcept
  42. {
  43. return value == rhs.value;
  44. }
  45. bool operator!=(const TableKey& rhs) const noexcept
  46. {
  47. return value != rhs.value;
  48. }
  49. bool operator<(const TableKey& rhs) const noexcept
  50. {
  51. return value < rhs.value;
  52. }
  53. bool operator>(const TableKey& rhs) const noexcept
  54. {
  55. return value > rhs.value;
  56. }
  57. explicit operator bool() const noexcept
  58. {
  59. return value != null_value;
  60. }
  61. uint32_t value;
  62. };
  63. inline std::ostream& operator<<(std::ostream& os, TableKey tk)
  64. {
  65. os << "TableKey(" << tk.value << ")";
  66. return os;
  67. }
  68. namespace util {
  69. inline std::string to_string(TableKey tk)
  70. {
  71. return to_string(tk.value);
  72. }
  73. } // namespace util
  74. class TableVersions : public std::vector<std::pair<TableKey, uint64_t>> {
  75. public:
  76. TableVersions() {}
  77. TableVersions(TableKey key, uint64_t version)
  78. {
  79. emplace_back(key, version);
  80. }
  81. bool operator==(const TableVersions& other) const;
  82. };
  83. struct ColKey {
  84. static constexpr int64_t null_value = int64_t(uint64_t(-1) >> 1); // free top bit
  85. struct Idx {
  86. unsigned val;
  87. };
  88. constexpr ColKey() noexcept
  89. : value(null_value)
  90. {
  91. }
  92. constexpr explicit ColKey(int64_t val) noexcept
  93. : value(val)
  94. {
  95. }
  96. constexpr ColKey(Idx index, ColumnType type, ColumnAttrMask attrs, uint64_t tag) noexcept
  97. : ColKey((index.val & 0xFFFFUL) | ((int(type) & 0x3FUL) << 16) | ((attrs.m_value & 0xFFUL) << 22) |
  98. ((tag & 0xFFFFFFFFUL) << 30))
  99. {
  100. }
  101. bool is_nullable() const
  102. {
  103. return get_attrs().test(col_attr_Nullable);
  104. }
  105. bool is_list() const
  106. {
  107. return get_attrs().test(col_attr_List);
  108. }
  109. bool is_set() const
  110. {
  111. return get_attrs().test(col_attr_Set);
  112. }
  113. bool is_dictionary() const
  114. {
  115. return get_attrs().test(col_attr_Dictionary);
  116. }
  117. bool is_collection() const
  118. {
  119. return get_attrs().test(col_attr_Collection);
  120. }
  121. ColKey& operator=(int64_t val) noexcept
  122. {
  123. value = val;
  124. return *this;
  125. }
  126. bool operator==(const ColKey& rhs) const noexcept
  127. {
  128. return value == rhs.value;
  129. }
  130. bool operator!=(const ColKey& rhs) const noexcept
  131. {
  132. return value != rhs.value;
  133. }
  134. bool operator<(const ColKey& rhs) const noexcept
  135. {
  136. return value < rhs.value;
  137. }
  138. bool operator>(const ColKey& rhs) const noexcept
  139. {
  140. return value > rhs.value;
  141. }
  142. explicit operator bool() const noexcept
  143. {
  144. return value != null_value;
  145. }
  146. Idx get_index() const noexcept
  147. {
  148. return Idx{static_cast<unsigned>(value) & 0xFFFFU};
  149. }
  150. ColumnType get_type() const noexcept
  151. {
  152. return ColumnType(ColumnType::Type((static_cast<unsigned>(value) >> 16) & 0x3F));
  153. }
  154. ColumnAttrMask get_attrs() const noexcept
  155. {
  156. return ColumnAttrMask((static_cast<unsigned>(value) >> 22) & 0xFF);
  157. }
  158. unsigned get_tag() const noexcept
  159. {
  160. return (value >> 30) & 0xFFFFFFFFUL;
  161. }
  162. int64_t value;
  163. };
  164. static_assert(ColKey::null_value == 0x7fffffffffffffff, "Fix this");
  165. inline std::ostream& operator<<(std::ostream& os, ColKey ck)
  166. {
  167. os << "ColKey(" << ck.value << ")";
  168. return os;
  169. }
  170. struct ObjKey {
  171. constexpr ObjKey() noexcept
  172. : value(-1)
  173. {
  174. }
  175. explicit constexpr ObjKey(int64_t val) noexcept
  176. : value(val)
  177. {
  178. }
  179. bool is_unresolved() const
  180. {
  181. return value <= -2;
  182. }
  183. ObjKey get_unresolved() const
  184. {
  185. return ObjKey(-2 - value);
  186. }
  187. ObjKey& operator=(int64_t val) noexcept
  188. {
  189. value = val;
  190. return *this;
  191. }
  192. bool operator==(const ObjKey& rhs) const noexcept
  193. {
  194. return value == rhs.value;
  195. }
  196. bool operator!=(const ObjKey& rhs) const noexcept
  197. {
  198. return value != rhs.value;
  199. }
  200. bool operator<(const ObjKey& rhs) const noexcept
  201. {
  202. return value < rhs.value;
  203. }
  204. bool operator<=(const ObjKey& rhs) const noexcept
  205. {
  206. return value <= rhs.value;
  207. }
  208. bool operator>(const ObjKey& rhs) const noexcept
  209. {
  210. return value > rhs.value;
  211. }
  212. bool operator>=(const ObjKey& rhs) const noexcept
  213. {
  214. return value >= rhs.value;
  215. }
  216. explicit operator bool() const noexcept
  217. {
  218. return value != -1;
  219. }
  220. int64_t value;
  221. private:
  222. // operator bool will enable casting to integer. Prevent this.
  223. operator int64_t() const = delete;
  224. };
  225. inline std::ostream& operator<<(std::ostream& ostr, ObjKey key)
  226. {
  227. ostr << "ObjKey(" << key.value << ")";
  228. return ostr;
  229. }
  230. class ObjKeys : public std::vector<ObjKey> {
  231. public:
  232. ObjKeys(const std::vector<int64_t>& init)
  233. {
  234. reserve(init.size());
  235. for (auto i : init) {
  236. emplace_back(i);
  237. }
  238. }
  239. ObjKeys() {}
  240. };
  241. struct ObjLink {
  242. public:
  243. ObjLink() {}
  244. ObjLink(TableKey table_key, ObjKey obj_key)
  245. : m_obj_key(obj_key)
  246. , m_table_key(table_key)
  247. {
  248. }
  249. explicit operator bool() const
  250. {
  251. return bool(m_table_key) && bool(m_obj_key);
  252. }
  253. bool is_null() const
  254. {
  255. return !bool(*this);
  256. }
  257. bool is_unresolved() const
  258. {
  259. return m_obj_key.is_unresolved();
  260. }
  261. bool operator==(const ObjLink& other) const
  262. {
  263. return m_obj_key == other.m_obj_key && m_table_key == other.m_table_key;
  264. }
  265. bool operator!=(const ObjLink& other) const
  266. {
  267. return m_obj_key != other.m_obj_key || m_table_key != other.m_table_key;
  268. }
  269. bool operator<(const ObjLink& rhs) const
  270. {
  271. if (m_table_key < rhs.m_table_key) {
  272. return true;
  273. }
  274. else if (m_table_key == rhs.m_table_key) {
  275. return m_obj_key < rhs.m_obj_key;
  276. }
  277. else {
  278. // m_table_key >= rhs.m_table_key
  279. return false;
  280. }
  281. }
  282. bool operator>(const ObjLink& rhs) const
  283. {
  284. return (*this != rhs) && !(*this < rhs);
  285. }
  286. TableKey get_table_key() const
  287. {
  288. return m_table_key;
  289. }
  290. ObjKey get_obj_key() const
  291. {
  292. return m_obj_key;
  293. }
  294. private:
  295. // Having ObjKey first ensures that there will be no uninitialized space
  296. // in the first 12 bytes. This is important when generating a hash
  297. ObjKey m_obj_key;
  298. TableKey m_table_key;
  299. };
  300. inline std::ostream& operator<<(std::ostream& os, ObjLink link)
  301. {
  302. os << '{' << link.get_table_key() << ',' << link.get_obj_key() << '}';
  303. return os;
  304. }
  305. constexpr ObjKey null_key;
  306. namespace util {
  307. inline std::string to_string(ColKey ck)
  308. {
  309. return to_string(ck.value);
  310. }
  311. } // namespace util
  312. } // namespace realm
  313. namespace std {
  314. template <>
  315. struct hash<realm::ObjKey> {
  316. size_t operator()(realm::ObjKey key) const
  317. {
  318. return std::hash<uint64_t>{}(key.value);
  319. }
  320. };
  321. } // namespace std
  322. #endif