| @@ -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() { | 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]]; | // Build an inverse map. Basically it means keys[i] should be relocated to keys[inverse[i]]; | ||||
| slot_allocator alloc(this->alloc_); | slot_allocator alloc(this->alloc_); | ||||
| slot_type *inverse = nullptr; | |||||
| try { | 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) { | } catch (std::bad_alloc &e) { | ||||
| return IndexRc::kOutOfMemory; | return IndexRc::kOutOfMemory; | ||||
| } catch (std::exception &e) { | } catch (std::exception &e) { | ||||
| return IndexRc::kUnexpectedError; | 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> | 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() { | 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]]; | // Build an inverse map. Basically it means keys[i] should be relocated to keys[inverse[i]]; | ||||
| slot_allocator alloc(this->alloc_); | slot_allocator alloc(this->alloc_); | ||||
| slot_type *inverse = nullptr; | |||||
| try { | 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) { | } catch (std::bad_alloc &e) { | ||||
| return IndexRc::kOutOfMemory; | return IndexRc::kOutOfMemory; | ||||
| } catch (std::exception &e) { | } catch (std::exception &e) { | ||||
| return IndexRc::kUnexpectedError; | 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> | template <typename K, typename V, typename A, typename C, typename T> | ||||