You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

btree_iterator.tpp 11 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /* COPYRIGHT 2019 Huawei Technologies Co., Ltd.All Rights Reserved.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #ifndef DATASET_UTIL_BTREE_ITERATOR_H_
  16. #define DATASET_UTIL_BTREE_ITERATOR_H_
  17. #include "utils/log_adapter.h"
  18. #include "btree.h"
  19. namespace mindspore {
  20. namespace dataset {
  21. template <typename K, typename V, typename A, typename C, typename T>
  22. BPlusTree<K, V, A, C, T>::Iterator::~Iterator() {
  23. if (locked_) {
  24. cur_->rw_lock_.Unlock();
  25. locked_ = false;
  26. }
  27. }
  28. template <typename K, typename V, typename A, typename C, typename T>
  29. typename BPlusTree<K, V, A, C, T>::Iterator &BPlusTree<K, V, A, C, T>::Iterator::operator++() {
  30. if (slot_ + 1u < cur_->slotuse_) {
  31. ++slot_;
  32. } else if (cur_->link_.next) {
  33. if (locked_) {
  34. cur_->link_.next->rw_lock_.LockShared();
  35. cur_->rw_lock_.Unlock();
  36. }
  37. cur_ = cur_->link_.next;
  38. slot_ = 0;
  39. } else {
  40. slot_ = cur_->slotuse_;
  41. }
  42. return *this;
  43. }
  44. template <typename K, typename V, typename A, typename C, typename T>
  45. typename BPlusTree<K, V, A, C, T>::Iterator BPlusTree<K, V, A, C, T>::Iterator::operator++(int) {
  46. Iterator tmp = *this;
  47. if (slot_ + 1u < cur_->slotuse_) {
  48. ++slot_;
  49. } else if (cur_->link_.next) {
  50. if (locked_) {
  51. cur_->link_.next->rw_lock_.LockShared();
  52. cur_->rw_lock_.Unlock();
  53. }
  54. cur_ = cur_->link_.next;
  55. slot_ = 0;
  56. } else {
  57. slot_ = cur_->slotuse_;
  58. }
  59. return tmp;
  60. }
  61. template <typename K, typename V, typename A, typename C, typename T>
  62. typename BPlusTree<K, V, A, C, T>::Iterator &BPlusTree<K, V, A, C, T>::Iterator::operator--() {
  63. if (slot_ > 0) {
  64. --slot_;
  65. } else if (cur_->link_.prev) {
  66. if (locked_) {
  67. cur_->link_.prev->rw_lock_.LockShared();
  68. cur_->rw_lock_.Unlock();
  69. }
  70. cur_ = cur_->link_.prev;
  71. slot_ = cur_->slotuse_ - 1;
  72. } else {
  73. slot_ = 0;
  74. }
  75. return *this;
  76. }
  77. template <typename K, typename V, typename A, typename C, typename T>
  78. typename BPlusTree<K, V, A, C, T>::Iterator BPlusTree<K, V, A, C, T>::Iterator::operator--(int) {
  79. Iterator tmp = *this;
  80. if (slot_ > 0) {
  81. --slot_;
  82. } else if (cur_->link_.prev) {
  83. if (locked_) {
  84. cur_->link_.prev->rw_lock_.LockShared();
  85. cur_->rw_lock_.Unlock();
  86. }
  87. cur_ = cur_->link_.prev;
  88. slot_ = cur_->slotuse_ - 1;
  89. } else {
  90. slot_ = 0;
  91. }
  92. return tmp;
  93. }
  94. template <typename K, typename V, typename A, typename C, typename T>
  95. BPlusTree<K, V, A, C, T>::Iterator::Iterator(const BPlusTree<K, V, A, C, T>::Iterator &lhs) {
  96. this->cur_ = lhs.cur_;
  97. this->slot_ = lhs.slot_;
  98. this->locked_ = lhs.locked_;
  99. if (this->locked_) {
  100. this->cur_->rw_lock_.LockShared();
  101. }
  102. }
  103. template <typename K, typename V, typename A, typename C, typename T>
  104. BPlusTree<K, V, A, C, T>::Iterator::Iterator(BPlusTree<K, V, A, C, T>::Iterator &&lhs) {
  105. this->cur_ = lhs.cur_;
  106. this->slot_ = lhs.slot_;
  107. this->locked_ = lhs.locked_;
  108. lhs.locked_ = false;
  109. lhs.slot_ = 0;
  110. lhs.cur_ = nullptr;
  111. }
  112. template <typename K, typename V, typename A, typename C, typename T>
  113. typename BPlusTree<K, V, A, C, T>::Iterator &BPlusTree<K, V, A, C, T>::Iterator::operator=(
  114. const BPlusTree<K, V, A, C, T>::Iterator &lhs) {
  115. if (*this != lhs) {
  116. if (this->locked_) {
  117. this->cur_->rw_lock_.Unlock();
  118. }
  119. this->cur_ = lhs.cur_;
  120. this->slot_ = lhs.slot_;
  121. this->locked_ = lhs.locked_;
  122. if (this->locked_) {
  123. this->cur_->rw_lock_.LockShared();
  124. }
  125. }
  126. return *this;
  127. }
  128. template <typename K, typename V, typename A, typename C, typename T>
  129. typename BPlusTree<K, V, A, C, T>::Iterator &BPlusTree<K, V, A, C, T>::Iterator::operator=(
  130. BPlusTree<K, V, A, C, T>::Iterator &&lhs) {
  131. if (*this != lhs) {
  132. if (this->locked_) {
  133. this->cur_->rw_lock_.Unlock();
  134. }
  135. this->cur_ = lhs.cur_;
  136. this->slot_ = lhs.slot_;
  137. this->locked_ = lhs.locked_;
  138. lhs.locked_ = false;
  139. lhs.slot_ = 0;
  140. lhs.cur_ = nullptr;
  141. }
  142. return *this;
  143. }
  144. template <typename K, typename V, typename A, typename C, typename T>
  145. BPlusTree<K, V, A, C, T>::ConstIterator::~ConstIterator() {
  146. if (locked_) {
  147. cur_->rw_lock_.Unlock();
  148. locked_ = false;
  149. }
  150. }
  151. template <typename K, typename V, typename A, typename C, typename T>
  152. typename BPlusTree<K, V, A, C, T>::ConstIterator &BPlusTree<K, V, A, C, T>::ConstIterator::operator++() {
  153. if (slot_ + 1u < cur_->slotuse_) {
  154. ++slot_;
  155. } else if (cur_->link_.next) {
  156. if (locked_) {
  157. cur_->link_.next->rw_lock_.LockShared();
  158. cur_->rw_lock_.Unlock();
  159. }
  160. cur_ = cur_->link_.next;
  161. slot_ = 0;
  162. } else {
  163. slot_ = cur_->slotuse_;
  164. }
  165. return *this;
  166. }
  167. template <typename K, typename V, typename A, typename C, typename T>
  168. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::ConstIterator::operator++(int) {
  169. Iterator tmp = *this;
  170. if (slot_ + 1u < cur_->slotuse_) {
  171. ++slot_;
  172. } else if (cur_->link_.next) {
  173. if (locked_) {
  174. cur_->link_.next->rw_lock_.LockShared();
  175. cur_->rw_lock_.Unlock();
  176. }
  177. cur_ = cur_->link_.next;
  178. slot_ = 0;
  179. } else {
  180. slot_ = cur_->slotuse_;
  181. }
  182. return tmp;
  183. }
  184. template <typename K, typename V, typename A, typename C, typename T>
  185. typename BPlusTree<K, V, A, C, T>::ConstIterator &BPlusTree<K, V, A, C, T>::ConstIterator::operator--() {
  186. if (slot_ > 0) {
  187. --slot_;
  188. } else if (cur_->link_.prev) {
  189. if (locked_) {
  190. cur_->link_.prev->rw_lock_.LockShared();
  191. cur_->rw_lock_.Unlock();
  192. }
  193. cur_ = cur_->link_.prev;
  194. slot_ = cur_->slotuse_ - 1;
  195. } else {
  196. slot_ = 0;
  197. }
  198. return *this;
  199. }
  200. template <typename K, typename V, typename A, typename C, typename T>
  201. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::ConstIterator::operator--(int) {
  202. Iterator tmp = *this;
  203. if (slot_ > 0) {
  204. --slot_;
  205. } else if (cur_->link_.prev) {
  206. if (locked_) {
  207. cur_->link_.prev->rw_lock_.LockShared();
  208. cur_->rw_lock_.Unlock();
  209. }
  210. cur_ = cur_->link_.prev;
  211. slot_ = cur_->slotuse_ - 1;
  212. } else {
  213. slot_ = 0;
  214. }
  215. return tmp;
  216. }
  217. template <typename K, typename V, typename A, typename C, typename T>
  218. BPlusTree<K, V, A, C, T>::ConstIterator::ConstIterator(const BPlusTree<K, V, A, C, T>::ConstIterator &lhs) {
  219. this->cur_ = lhs.cur_;
  220. this->slot_ = lhs.slot_;
  221. this->locked_ = lhs.locked_;
  222. if (this->locked_) {
  223. this->cur_->rw_lock_.LockShared();
  224. }
  225. }
  226. template <typename K, typename V, typename A, typename C, typename T>
  227. BPlusTree<K, V, A, C, T>::ConstIterator::ConstIterator(BPlusTree<K, V, A, C, T>::ConstIterator &&lhs) {
  228. this->cur_ = lhs.cur_;
  229. this->slot_ = lhs.slot_;
  230. this->locked_ = lhs.locked_;
  231. lhs.locked_ = false;
  232. lhs.slot_ = 0;
  233. lhs.cur_ = nullptr;
  234. }
  235. template <typename K, typename V, typename A, typename C, typename T>
  236. typename BPlusTree<K, V, A, C, T>::ConstIterator &BPlusTree<K, V, A, C, T>::ConstIterator::operator=(
  237. const BPlusTree<K, V, A, C, T>::ConstIterator &lhs) {
  238. if (*this != lhs) {
  239. if (this->locked_) {
  240. this->cur_->rw_lock_.Unlock();
  241. }
  242. this->cur_ = lhs.cur_;
  243. this->slot_ = lhs.slot_;
  244. this->locked_ = lhs.locked_;
  245. if (this->locked_) {
  246. this->cur_->rw_lock_.LockShared();
  247. }
  248. }
  249. return *this;
  250. }
  251. template <typename K, typename V, typename A, typename C, typename T>
  252. typename BPlusTree<K, V, A, C, T>::ConstIterator &BPlusTree<K, V, A, C, T>::ConstIterator::operator=(
  253. BPlusTree<K, V, A, C, T>::ConstIterator &&lhs) {
  254. if (*this != lhs) {
  255. if (this->locked_) {
  256. this->cur_->rw_lock_.Unlock();
  257. }
  258. this->cur_ = lhs.cur_;
  259. this->slot_ = lhs.slot_;
  260. this->locked_ = lhs.locked_;
  261. lhs.locked_ = false;
  262. lhs.slot_ = 0;
  263. lhs.cur_ = nullptr;
  264. }
  265. return *this;
  266. }
  267. template <typename K, typename V, typename A, typename C, typename T>
  268. std::pair<typename BPlusTree<K, V, A, C, T>::ConstIterator, bool> BPlusTree<K, V, A, C, T>::Search(
  269. const key_type &key) const {
  270. if (root_ != nullptr) {
  271. LeafNode *leaf = nullptr;
  272. slot_type slot;
  273. RWLock *myLock = &this->rw_lock_;
  274. // Lock the tree in S, pass the lock to Locate which will unlock it for us underneath.
  275. myLock->LockShared();
  276. IndexRc rc = Locate(myLock, false, root_, key, &leaf, &slot);
  277. bool find = (rc == IndexRc::kOk);
  278. return std::make_pair(ConstIterator(leaf, slot, find), find);
  279. } else {
  280. return std::make_pair(cend(), false);
  281. }
  282. }
  283. template <typename K, typename V, typename A, typename C, typename T>
  284. std::pair<typename BPlusTree<K, V, A, C, T>::Iterator, bool> BPlusTree<K, V, A, C, T>::Search(const key_type &key) {
  285. if (root_ != nullptr) {
  286. LeafNode *leaf = nullptr;
  287. slot_type slot;
  288. RWLock *myLock = &this->rw_lock_;
  289. // Lock the tree in S, pass the lock to Locate which will unlock it for us underneath.
  290. myLock->LockShared();
  291. IndexRc rc = Locate(myLock, false, root_, key, &leaf, &slot);
  292. bool find = (rc == IndexRc::kOk);
  293. return std::make_pair(Iterator(leaf, slot, find), find);
  294. } else {
  295. return std::make_pair(end(), false);
  296. }
  297. }
  298. template <typename K, typename V, typename A, typename C, typename T>
  299. typename BPlusTree<K, V, A, C, T>::value_type BPlusTree<K, V, A, C, T>::operator[](key_type key) {
  300. auto r = Search(key);
  301. return r.first.value();
  302. }
  303. template <typename K, typename V, typename A, typename C, typename T>
  304. typename BPlusTree<K, V, A, C, T>::Iterator BPlusTree<K, V, A, C, T>::begin() {
  305. return Iterator(this);
  306. }
  307. template <typename K, typename V, typename A, typename C, typename T>
  308. typename BPlusTree<K, V, A, C, T>::Iterator BPlusTree<K, V, A, C, T>::end() {
  309. return Iterator(this->leaf_nodes_.tail, this->leaf_nodes_.tail ? this->leaf_nodes_.tail->slotuse_ : 0);
  310. }
  311. template <typename K, typename V, typename A, typename C, typename T>
  312. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::begin() const {
  313. return ConstIterator(this);
  314. }
  315. template <typename K, typename V, typename A, typename C, typename T>
  316. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::end() const {
  317. return ConstIterator(this->leaf_nodes_.tail, this->leaf_nodes_.tail ? this->leaf_nodes_.tail->slotuse_ : 0);
  318. }
  319. template <typename K, typename V, typename A, typename C, typename T>
  320. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::cbegin() const {
  321. return ConstIterator(this);
  322. }
  323. template <typename K, typename V, typename A, typename C, typename T>
  324. typename BPlusTree<K, V, A, C, T>::ConstIterator BPlusTree<K, V, A, C, T>::cend() const {
  325. return ConstIterator(this->leaf_nodes_.tail, this->leaf_nodes_.tail ? this->leaf_nodes_.tail->slotuse_ : 0);
  326. }
  327. } // namespace dataset
  328. } // namespace mindspore
  329. #endif