| @@ -23,41 +23,39 @@ template <typename K, typename V, typename A, typename C, typename T> | |||
| typename BPlusTree<K, V, A, C, T>::IndexRc BPlusTree<K, V, A, C, T>::InnerNode::Sort() { | |||
| // Build an inverse map. Basically it means keys[i] should be relocated to keys[inverse[i]]; | |||
| slot_allocator alloc(this->alloc_); | |||
| slot_type *inverse = nullptr; | |||
| try { | |||
| inverse = alloc.allocate(traits::kInnerSlots); | |||
| // We use a unique_ptr will custom deleter to ensure the memory will be released when this | |||
| // function returns. | |||
| std::unique_ptr<slot_type[], std::function<void(slot_type *)>> memGuard( | |||
| alloc.allocate(traits::kInnerSlots), [&alloc](slot_type *p) { alloc.deallocate(p, traits::kInnerSlots); }); | |||
| slot_type *inverse = memGuard.get(); | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| inverse[slot_dir_[i]] = i; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| while (inverse[i] != i) { | |||
| slot_type j = inverse[i]; | |||
| slot_type k = inverse[j]; | |||
| // Swap the key | |||
| std::swap(keys_[j], keys_[i]); | |||
| // Swap the pointers. | |||
| if ((j + 1) >= traits::kInnerSlots + 1 || (i + 1) >= traits::kInnerSlots + 1) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| std::swap(data_[j + 1], data_[i + 1]); | |||
| // one key in order. | |||
| inverse[j] = j; | |||
| // continue to move | |||
| inverse[i] = k; | |||
| } | |||
| slot_dir_[i] = i; | |||
| } | |||
| return IndexRc::kOk; | |||
| } catch (std::bad_alloc &e) { | |||
| return IndexRc::kOutOfMemory; | |||
| } catch (std::exception &e) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| inverse[slot_dir_[i]] = i; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| while (inverse[i] != i) { | |||
| slot_type j = inverse[i]; | |||
| slot_type k = inverse[j]; | |||
| // Swap the key | |||
| std::swap(keys_[j], keys_[i]); | |||
| // Swap the pointers. | |||
| if ((j + 1) >= traits::kInnerSlots + 1 || (i + 1) >= traits::kInnerSlots + 1) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| std::swap(data_[j + 1], data_[i + 1]); | |||
| // one key in order. | |||
| inverse[j] = j; | |||
| // continue to move | |||
| inverse[i] = k; | |||
| } | |||
| slot_dir_[i] = i; | |||
| } | |||
| if (inverse != nullptr) { | |||
| alloc.deallocate(inverse, traits::kInnerSlots); | |||
| inverse = nullptr; | |||
| } | |||
| return IndexRc::kOk; | |||
| } | |||
| template <typename K, typename V, typename A, typename C, typename T> | |||
| @@ -117,41 +115,39 @@ template <typename K, typename V, typename A, typename C, typename T> | |||
| typename BPlusTree<K, V, A, C, T>::IndexRc BPlusTree<K, V, A, C, T>::LeafNode::Sort() { | |||
| // Build an inverse map. Basically it means keys[i] should be relocated to keys[inverse[i]]; | |||
| slot_allocator alloc(this->alloc_); | |||
| slot_type *inverse = nullptr; | |||
| try { | |||
| inverse = alloc.allocate(traits::kLeafSlots); | |||
| // We use a unique_ptr will custom deleter to ensure the memory will be released when this | |||
| // function returns. | |||
| std::unique_ptr<slot_type[], std::function<void(slot_type *)>> memGuard( | |||
| alloc.allocate(traits::kLeafSlots), [&alloc](slot_type *p) { alloc.deallocate(p, traits::kLeafSlots); }); | |||
| slot_type *inverse = memGuard.get(); | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| inverse[slot_dir_[i]] = i; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| while (inverse[i] != i) { | |||
| slot_type j = inverse[i]; | |||
| slot_type k = inverse[j]; | |||
| // Swap the key | |||
| if (j >= traits::kLeafSlots || i >= traits::kLeafSlots) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| std::swap(keys_[j], keys_[i]); | |||
| // Swap the shared pointers | |||
| std::swap(data_[j], data_[i]); | |||
| // one key in order. | |||
| inverse[j] = j; | |||
| // continue to move | |||
| inverse[i] = k; | |||
| } | |||
| slot_dir_[i] = i; | |||
| } | |||
| return IndexRc::kOk; | |||
| } catch (std::bad_alloc &e) { | |||
| return IndexRc::kOutOfMemory; | |||
| } catch (std::exception &e) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| inverse[slot_dir_[i]] = i; | |||
| } | |||
| for (slot_type i = 0; i < slotuse_; i++) { | |||
| while (inverse[i] != i) { | |||
| slot_type j = inverse[i]; | |||
| slot_type k = inverse[j]; | |||
| // Swap the key | |||
| if (j >= traits::kLeafSlots || i >= traits::kLeafSlots) { | |||
| return IndexRc::kUnexpectedError; | |||
| } | |||
| std::swap(keys_[j], keys_[i]); | |||
| // Swap the shared pointers | |||
| std::swap(data_[j], data_[i]); | |||
| // one key in order. | |||
| inverse[j] = j; | |||
| // continue to move | |||
| inverse[i] = k; | |||
| } | |||
| slot_dir_[i] = i; | |||
| } | |||
| if (inverse != nullptr) { | |||
| alloc.deallocate(inverse, traits::kLeafSlots); | |||
| inverse = nullptr; | |||
| } | |||
| return IndexRc::kOk; | |||
| } | |||
| template <typename K, typename V, typename A, typename C, typename T> | |||