diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-03-03 21:55:04 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-03-03 21:55:04 +0100 |
commit | 0b266f7959130ff8561ee6caf3dd5084e1f56992 (patch) | |
tree | fbcab28f24a3c21b1350c1b29168febb3e295b07 | |
parent | d538dbc39a3f8da7160c6f0c034ff40824cd4bed (diff) |
Use AtomicEntryRef as key for unique store btree dictionary.
30 files changed, 184 insertions, 159 deletions
diff --git a/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp b/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp index 8c3d7173ae3..1d76473754f 100644 --- a/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp +++ b/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp @@ -11,6 +11,8 @@ LOG_SETUP("enum_comparator_test"); using namespace vespalib::btree; +using vespalib::datastore::AtomicEntryRef; + namespace search { using NumericEnumStore = EnumStoreT<int32_t>; @@ -19,7 +21,7 @@ using StringEnumStore = EnumStoreT<const char*>; using EnumIndex = IEnumStore::Index; -using TreeType = BTreeRoot<EnumIndex, BTreeNoLeafData, +using TreeType = BTreeRoot<AtomicEntryRef, BTreeNoLeafData, vespalib::btree::NoAggregated, const vespalib::datastore::EntryComparatorWrapper>; using NodeAllocator = TreeType::NodeAllocatorType; @@ -133,14 +135,14 @@ TEST("requireThatComparatorWithTreeIsWorking") NodeAllocator m; for (int32_t v = 100; v > 0; --v) { auto cmp = es.make_comparator(v); - EXPECT_FALSE(t.find(EnumIndex(), m, cmp).valid()); + EXPECT_FALSE(t.find(AtomicEntryRef(), m, cmp).valid()); EnumIndex idx = es.insert(v); - t.insert(idx, BTreeNoLeafData(), m, cmp); + t.insert(AtomicEntryRef(idx), BTreeNoLeafData(), m, cmp); } EXPECT_EQUAL(100u, t.size(m)); int32_t exp = 1; for (TreeType::Iterator itr = t.begin(m); itr.valid(); ++itr) { - EXPECT_EQUAL(exp++, es.get_value(itr.getKey())); + EXPECT_EQUAL(exp++, es.get_value(itr.getKey().load_relaxed())); } EXPECT_EQUAL(101, exp); t.clear(m); diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp index 99fdd9f4b0a..c360bad6d75 100644 --- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp +++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp @@ -8,6 +8,7 @@ LOG_SETUP("enumstore_test"); using Type = search::DictionaryConfig::Type; +using vespalib::datastore::AtomicEntryRef; using vespalib::datastore::CompactionStrategy; using vespalib::datastore::EntryRef; using vespalib::datastore::EntryRefFilter; @@ -222,7 +223,7 @@ testUniques(const StringEnumStore& ses, const std::vector<std::string>& unique) read_snapshot->fill(); read_snapshot->sort(); std::vector<EnumIndex> saved_indexes; - read_snapshot->foreach_key([&saved_indexes](EntryRef idx) { saved_indexes.push_back(idx); }); + read_snapshot->foreach_key([&saved_indexes](const AtomicEntryRef& idx) { saved_indexes.push_back(idx.load_acquire()); }); uint32_t i = 0; for (auto idx : saved_indexes) { EXPECT_TRUE(strcmp(unique[i].c_str(), ses.get_value(idx)) == 0); @@ -936,7 +937,7 @@ TYPED_TEST(EnumStoreDictionaryTest, compact_worst_works) auto& mystore = this->store; read_snapshot->fill(); read_snapshot->sort(); - read_snapshot->foreach_key([&values, &mystore](EntryRef idx) { values.push_back(mystore.get_value(idx)); }); + read_snapshot->foreach_key([&values, &mystore](const AtomicEntryRef& idx) { values.push_back(mystore.get_value(idx.load_acquire())); }); EXPECT_EQ(exp_values, values); } diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp index 8bc28abc238..94e102fb5d8 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp @@ -10,6 +10,7 @@ #include <vespa/log/log.h> LOG_SETUP(".searchlib.attribute.enum_store_dictionary"); +using vespalib::datastore::AtomicEntryRef; using vespalib::datastore::EntryRef; using vespalib::datastore::UniqueStoreAddResult; @@ -45,7 +46,7 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::free_unused_values(const // find unused enums if constexpr (has_btree_dictionary) { for (auto iter = this->_btree_dict.begin(); iter.valid(); ++iter) { - _enumStore.free_value_if_unused(iter.getKey(), unused); + _enumStore.free_value_if_unused(iter.getKey().load_relaxed(), unused); } } else { this->_hash_dict.foreach_key([this, &unused](EntryRef ref) { @@ -78,8 +79,8 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::remove(const EntryCompar { assert(ref.valid()); if constexpr (has_btree_dictionary) { - auto itr = this->_btree_dict.lowerBound(ref, comp); - assert(itr.valid() && itr.getKey() == ref); + auto itr = this->_btree_dict.lowerBound(AtomicEntryRef(ref), comp); + assert(itr.valid() && itr.getKey().load_relaxed() == ref); if constexpr (std::is_same_v<BTreeDictionaryT, EnumPostingTree>) { assert(EntryRef(itr.getData()) == EntryRef()); } @@ -98,16 +99,16 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::find_index(const EntryCo if constexpr (has_hash_dictionary) { auto find_result = this->_hash_dict.find(cmp, EntryRef()); if (find_result != nullptr) { - idx = find_result->first.load_acquire(); + idx = find_result->first.load_relaxed(); return true; } return false; } else { - auto itr = this->_btree_dict.find(Index(), cmp); + auto itr = this->_btree_dict.find(AtomicEntryRef(), cmp); if (!itr.valid()) { return false; } - idx = itr.getKey(); + idx = itr.getKey().load_relaxed(); return true; } } @@ -124,11 +125,11 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::find_frozen_index(const } return false; } else { - auto itr = this->_btree_dict.getFrozenView().find(Index(), cmp); + auto itr = this->_btree_dict.getFrozenView().find(AtomicEntryRef(), cmp); if (!itr.valid()) { return false; } - idx = itr.getKey(); + idx = itr.getKey().load_acquire(); return true; } } @@ -139,9 +140,9 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::find_matching_enums(cons { std::vector<IEnumStore::EnumHandle> result; if constexpr (has_btree_dictionary) { - auto itr = this->_btree_dict.getFrozenView().find(Index(), cmp); - while (itr.valid() && !cmp.less(Index(), itr.getKey())) { - result.push_back(itr.getKey().ref()); + auto itr = this->_btree_dict.getFrozenView().find(AtomicEntryRef(), cmp); + while (itr.valid() && !cmp.less(Index(), itr.getKey().load_acquire())) { + result.push_back(itr.getKey().load_acquire().ref()); ++itr; } } else { @@ -184,9 +185,9 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::find_posting_list(const return std::make_pair(Index(), EntryRef()); } else { typename BTreeDictionaryType::ConstIterator itr(vespalib::btree::BTreeNode::Ref(), this->_btree_dict.getAllocator()); - itr.lower_bound(root, Index(), cmp); - if (itr.valid() && !cmp.less(Index(), itr.getKey())) { - return std::make_pair(itr.getKey(), EntryRef(itr.getData())); + itr.lower_bound(root, AtomicEntryRef(), cmp); + if (itr.valid() && !cmp.less(Index(), itr.getKey().load_acquire())) { + return std::make_pair(itr.getKey().load_acquire(), EntryRef(itr.getData())); } return std::make_pair(Index(), EntryRef()); } @@ -250,8 +251,8 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::update_posting_list(Inde { if constexpr (has_btree_dictionary) { auto& dict = this->_btree_dict; - auto itr = dict.lowerBound(idx, cmp); - assert(itr.valid() && itr.getKey() == idx); + auto itr = dict.lowerBound(AtomicEntryRef(idx), cmp); + assert(itr.valid() && itr.getKey().load_relaxed() == idx); EntryRef old_posting_idx(itr.getData()); EntryRef new_posting_idx = updater(old_posting_idx); // Note: Needs review when porting to other platforms @@ -297,8 +298,8 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::normalize_posting_lists( std::atomic_thread_fence(std::memory_order_release); itr.writeData(new_posting_idx.ref()); if constexpr (has_hash_dictionary) { - auto find_result = this->_hash_dict.find(this->_hash_dict.get_default_comparator(), itr.getKey()); - assert(find_result != nullptr && find_result->first.load_relaxed() == itr.getKey()); + auto find_result = this->_hash_dict.find(this->_hash_dict.get_default_comparator(), itr.getKey().load_relaxed()); + assert(find_result != nullptr && find_result->first.load_relaxed() == itr.getKey().load_relaxed()); assert(find_result->second.load_relaxed() == old_posting_idx); find_result->second.store_release(new_posting_idx); } @@ -415,7 +416,7 @@ EnumStoreDictionary<BTreeDictionaryT, HashDictionaryT>::normalize_posting_lists( if (ref.valid()) { if (filter.has(ref)) { refs.emplace_back(ref); - change_writer.emplace_back(itr.getKey(), itr.getWData()); + change_writer.emplace_back(itr.getKey().load_relaxed(), itr.getWData()); if (refs.size() >= refs.capacity()) { normalize(refs); changed |= change_writer.write(refs); @@ -502,21 +503,21 @@ UniqueStoreAddResult EnumStoreFoldedDictionary::add(const EntryComparator& comp, std::function<EntryRef(void)> insertEntry) { static_assert(!has_hash_dictionary, "Folded Dictionary does not support hash dictionary"); - auto it = _btree_dict.lowerBound(EntryRef(), comp); - if (it.valid() && !comp.less(EntryRef(), it.getKey())) { + auto it = _btree_dict.lowerBound(AtomicEntryRef(), comp); + if (it.valid() && !comp.less(EntryRef(), it.getKey().load_relaxed())) { // Entry already exists - return UniqueStoreAddResult(it.getKey(), false); + return UniqueStoreAddResult(it.getKey().load_relaxed(), false); } EntryRef newRef = insertEntry(); - _btree_dict.insert(it, newRef, EntryRef().ref()); + _btree_dict.insert(it, AtomicEntryRef(newRef), EntryRef().ref()); // Maybe move posting list reference from next entry ++it; - if (it.valid() && EntryRef(it.getData()).valid() && !_folded_compare->less(newRef, it.getKey())) { + if (it.valid() && EntryRef(it.getData()).valid() && !_folded_compare->less(newRef, it.getKey().load_relaxed())) { EntryRef posting_list_ref(it.getData()); _btree_dict.thaw(it); it.writeData(EntryRef().ref()); --it; - assert(it.valid() && it.getKey() == newRef); + assert(it.valid() && it.getKey().load_relaxed() == newRef); it.writeData(posting_list_ref.ref()); } return UniqueStoreAddResult(newRef, true); @@ -527,13 +528,13 @@ EnumStoreFoldedDictionary::remove(const EntryComparator& comp, EntryRef ref) { static_assert(!has_hash_dictionary, "Folded Dictionary does not support hash dictionary"); assert(ref.valid()); - auto it = _btree_dict.lowerBound(ref, comp); - assert(it.valid() && it.getKey() == ref); + auto it = _btree_dict.lowerBound(AtomicEntryRef(ref), comp); + assert(it.valid() && it.getKey().load_relaxed() == ref); EntryRef posting_list_ref(it.getData()); _btree_dict.remove(it); // Maybe copy posting list reference to next entry if (posting_list_ref.valid()) { - if (it.valid() && !EntryRef(it.getData()).valid() && !_folded_compare->less(ref, it.getKey())) { + if (it.valid() && !EntryRef(it.getData()).valid() && !_folded_compare->less(ref, it.getKey().load_relaxed())) { this->_btree_dict.thaw(it); it.writeData(posting_list_ref.ref()); } else { @@ -546,9 +547,9 @@ void EnumStoreFoldedDictionary::collect_folded(Index idx, EntryRef root, const std::function<void(EntryRef)>& callback) const { BTreeDictionaryType::ConstIterator itr(vespalib::btree::BTreeNode::Ref(), _btree_dict.getAllocator()); - itr.lower_bound(root, idx, *_folded_compare); - while (itr.valid() && !_folded_compare->less(idx, itr.getKey())) { - callback(itr.getKey()); + itr.lower_bound(root, AtomicEntryRef(idx), *_folded_compare); + while (itr.valid() && !_folded_compare->less(idx, itr.getKey().load_acquire())) { + callback(itr.getKey().load_acquire()); ++itr; } } @@ -556,9 +557,9 @@ EnumStoreFoldedDictionary::collect_folded(Index idx, EntryRef root, const std::f IEnumStore::Index EnumStoreFoldedDictionary::remap_index(Index idx) { - auto itr = _btree_dict.find(idx, *_folded_compare); + auto itr = _btree_dict.find(AtomicEntryRef(idx), *_folded_compare); assert(itr.valid()); - return itr.getKey(); + return itr.getKey().load_acquire(); } template class EnumStoreDictionary<EnumTree>; @@ -578,94 +579,94 @@ using search::EnumTreeTraits; using datastore::EntryComparatorWrapper; template -class BTreeNodeT<IEnumStore::Index, EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeNodeT<AtomicEntryRef, EnumTreeTraits::INTERNAL_SLOTS>; template -class BTreeNodeTT<IEnumStore::Index, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeNodeTT<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; template -class BTreeNodeTT<IEnumStore::Index, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class BTreeNodeTT<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeInternalNode<IEnumStore::Index, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeInternalNode<AtomicEntryRef, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; template -class BTreeLeafNode<IEnumStore::Index, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNode<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeLeafNode<IEnumStore::Index, uint32_t, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNode<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeLeafNodeTemp<IEnumStore::Index, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNodeTemp<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeLeafNodeTemp<IEnumStore::Index, uint32_t, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNodeTemp<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeNodeStore<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeNodeStore<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeNodeStore<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeNodeStore<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeRoot<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeRoot<AtomicEntryRef, BTreeNoLeafData, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeRoot<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeRoot<AtomicEntryRef, uint32_t, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeRootT<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeRootT<AtomicEntryRef, BTreeNoLeafData, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeRootT<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeRootT<AtomicEntryRef, uint32_t, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeRootBase<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeRootBase<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeRootBase<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeRootBase<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeNodeAllocator<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeNodeAllocator<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeNodeAllocator<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeNodeAllocator<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class BTreeIteratorBase<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeIteratorBase<AtomicEntryRef, BTreeNoLeafData, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; template -class BTreeIteratorBase<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeIteratorBase<AtomicEntryRef, uint32_t, NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; -template class BTreeConstIterator<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +template class BTreeConstIterator<AtomicEntryRef, BTreeNoLeafData, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; -template class BTreeConstIterator<IEnumStore::Index, uint32_t, NoAggregated, +template class BTreeConstIterator<AtomicEntryRef, uint32_t, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeIterator<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeIterator<AtomicEntryRef, BTreeNoLeafData, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTreeIterator<IEnumStore::Index, uint32_t, NoAggregated, +class BTreeIterator<AtomicEntryRef, uint32_t, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTree<IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTree<AtomicEntryRef, BTreeNoLeafData, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; template -class BTree<IEnumStore::Index, uint32_t, NoAggregated, +class BTree<AtomicEntryRef, uint32_t, NoAggregated, const EntryComparatorWrapper, EnumTreeTraits>; } diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h index db1176c5484..57262bc90aa 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h @@ -15,6 +15,7 @@ class IEnumStore; template <typename BTreeDictionaryT, typename HashDictionaryT = vespalib::datastore::NoHashDictionary> class EnumStoreDictionary : public vespalib::datastore::UniqueStoreDictionary<BTreeDictionaryT, IEnumStoreDictionary, HashDictionaryT> { protected: + using AtomicEntryRef = IEnumStoreDictionary::AtomicEntryRef; using EntryRef = IEnumStoreDictionary::EntryRef; using EntryRefFilter = IEnumStoreDictionary::EntryRefFilter; using Index = IEnumStoreDictionary::Index; @@ -88,95 +89,95 @@ public: namespace vespalib::btree { extern template -class BTreeNodeT<search::IEnumStore::Index, search::EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeNodeT<datastore::AtomicEntryRef, search::EnumTreeTraits::INTERNAL_SLOTS>; extern template -class BTreeNodeTT<search::IEnumStore::Index, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeNodeTT<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS>; extern template -class BTreeNodeTT<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; +class BTreeNodeTT<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeInternalNode<search::IEnumStore::Index, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS>; +class BTreeInternalNode<datastore::AtomicEntryRef, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS>; extern template -class BTreeLeafNode<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNode<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeLeafNode<search::IEnumStore::Index, uint32_t, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNode<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeLeafNodeTemp<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNodeTemp<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeLeafNodeTemp<search::IEnumStore::Index, uint32_t, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; +class BTreeLeafNodeTemp<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeNodeStore<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeNodeStore<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeNodeStore<search::IEnumStore::Index, uint32_t, NoAggregated, +class BTreeNodeStore<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeRoot<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeRoot<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeRoot<search::IEnumStore::Index, uint32_t, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeRoot<datastore::AtomicEntryRef, uint32_t, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeRootT<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeRootT<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeRootT<search::IEnumStore::Index, uint32_t, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeRootT<datastore::AtomicEntryRef, uint32_t, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeRootBase<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeRootBase<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeRootBase<search::IEnumStore::Index, uint32_t, NoAggregated, +class BTreeRootBase<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeNodeAllocator<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeNodeAllocator<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeNodeAllocator<search::IEnumStore::Index, uint32_t, NoAggregated, +class BTreeNodeAllocator<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS>; extern template -class BTreeIteratorBase<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, +class BTreeIteratorBase<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS, search::EnumTreeTraits::PATH_SIZE>; extern template -class BTreeIteratorBase<search::IEnumStore::Index, uint32_t, NoAggregated, +class BTreeIteratorBase<datastore::AtomicEntryRef, uint32_t, NoAggregated, search::EnumTreeTraits::INTERNAL_SLOTS, search::EnumTreeTraits::LEAF_SLOTS, search::EnumTreeTraits::PATH_SIZE>; -extern template class BTreeConstIterator<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +extern template class BTreeConstIterator<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; -extern template class BTreeConstIterator<search::IEnumStore::Index, uint32_t, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +extern template class BTreeConstIterator<datastore::AtomicEntryRef, uint32_t, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeIterator<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeIterator<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTreeIterator<search::IEnumStore::Index, uint32_t, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTreeIterator<datastore::AtomicEntryRef, uint32_t, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTree<search::IEnumStore::Index, BTreeNoLeafData, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTree<datastore::AtomicEntryRef, BTreeNoLeafData, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; extern template -class BTree<search::IEnumStore::Index, uint32_t, NoAggregated, - const vespalib::datastore::EntryComparatorWrapper, search::EnumTreeTraits>; +class BTree<datastore::AtomicEntryRef, uint32_t, NoAggregated, + const datastore::EntryComparatorWrapper, search::EnumTreeTraits>; } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp index 0ebf5a2913d..74a37ca8394 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp @@ -24,8 +24,8 @@ EnumAttributeSaver::writeUdat(IAttributeSaveTarget &saveTarget) { if (saveTarget.getEnumerated()) { auto udatWriter = saveTarget.udatWriter().allocBufferWriter(); - _enumerator->foreach_key([&](vespalib::datastore::EntryRef idx){ - _enumStore.write_value(*udatWriter, idx); + _enumerator->foreach_key([&](const vespalib::datastore::AtomicEntryRef& idx){ + _enumStore.write_value(*udatWriter, idx.load_acquire()); }); udatWriter->flush(); } diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h index e3782514530..b4e86e2a60c 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h @@ -4,7 +4,7 @@ #include "enum_store_loaders.h" #include "enum_store_types.h" -#include <vespa/vespalib/datastore/entryref.h> +#include <vespa/vespalib/datastore/atomic_entry_ref.h> #include <vespa/vespalib/datastore/unique_store_enumerator.h> namespace vespalib { diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h index a9716ec5d05..d9cb6df36ee 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h @@ -13,12 +13,12 @@ class BufferWriter; using EnumTreeTraits = vespalib::btree::BTreeTraits<16, 16, 10, true>; -using EnumTree = vespalib::btree::BTree<IEnumStore::Index, vespalib::btree::BTreeNoLeafData, +using EnumTree = vespalib::btree::BTree<vespalib::datastore::AtomicEntryRef, vespalib::btree::BTreeNoLeafData, vespalib::btree::NoAggregated, const vespalib::datastore::EntryComparatorWrapper, EnumTreeTraits>; -using EnumPostingTree = vespalib::btree::BTree<IEnumStore::Index, uint32_t, +using EnumPostingTree = vespalib::btree::BTree<vespalib::datastore::AtomicEntryRef, uint32_t, vespalib::btree::NoAggregated, const vespalib::datastore::EntryComparatorWrapper, EnumTreeTraits>; @@ -28,6 +28,7 @@ using EnumPostingTree = vespalib::btree::BTree<IEnumStore::Index, uint32_t, */ class IEnumStoreDictionary : public vespalib::datastore::IUniqueStoreDictionary { public: + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; using EntryRef = vespalib::datastore::EntryRef; using EntryComparator = vespalib::datastore::EntryComparator; using EntryRefFilter = vespalib::datastore::EntryRefFilter; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp index f8339c05d4c..7eb08de7503 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp @@ -61,10 +61,10 @@ PostingListSearchContext::lookupRange(const vespalib::datastore::EntryComparator _uniqueValues = 2; // Avoid zero and single value optimizations, use filtering return; } - _lowerDictItr.lower_bound(_frozenDictionary.getRoot(), EnumIndex(), low); + _lowerDictItr.lower_bound(_frozenDictionary.getRoot(), AtomicEntryRef(), low); _upperDictItr = _lowerDictItr; - if (_upperDictItr.valid() && !high.less(EnumIndex(), _upperDictItr.getKey())) { - _upperDictItr.seekPast(EnumIndex(), high); + if (_upperDictItr.valid() && !high.less(EnumIndex(), _upperDictItr.getKey().load_acquire())) { + _upperDictItr.seekPast(AtomicEntryRef(), high); } _uniqueValues = _upperDictItr - _lowerDictItr; } diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h index 318dc4dc6c5..97c2c7d2b63 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h @@ -24,6 +24,7 @@ class ISearchContext; class PostingListSearchContext : public IPostingListSearchContext { protected: + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; using Dictionary = EnumPostingTree; using DictionaryConstIterator = Dictionary::ConstIterator; using FrozenDictionary = Dictionary::FrozenView; @@ -101,6 +102,7 @@ protected: using Traits = PostingListTraits<DataType>; using PostingList = typename Traits::PostingList; using Posting = typename Traits::Posting; + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; using EntryRef = vespalib::datastore::EntryRef; using FrozenView = typename PostingList::BTreeType::FrozenView; @@ -295,10 +297,10 @@ bool StringPostingSearchContext<BaseSC, AttrT, DataT>::useThis(const PostingListSearchContext::DictionaryConstIterator & it) const { if ( this->isRegex() ) { return this->getRegex().valid() - ? this->getRegex().partial_match(_enumStore.get_value(it.getKey())) + ? this->getRegex().partial_match(_enumStore.get_value(it.getKey().load_acquire())) : false; } else if ( this->isCased() ) { - return this->isMatch(_enumStore.get_value(it.getKey())); + return this->isMatch(_enumStore.get_value(it.getKey().load_acquire())); } return true; } @@ -354,10 +356,10 @@ getIterators(bool shouldApplyRangeLimit) } if (this->_lowerDictItr != this->_upperDictItr) { - _low = _enumStore.get_value(this->_lowerDictItr.getKey()); + _low = _enumStore.get_value(this->_lowerDictItr.getKey().load_acquire()); auto last = this->_upperDictItr; --last; - _high = _enumStore.get_value(last.getKey()); + _high = _enumStore.get_value(last.getKey().load_acquire()); } } diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp index f7317f2d8c6..57ff5ef464f 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp @@ -56,8 +56,8 @@ ReferenceAttribute::~ReferenceAttribute() incGeneration(); // Force freeze const auto &store = _store; const auto enumerator = _store.getEnumerator(true); - enumerator.foreach_key([&store,this](EntryRef ref) - { const Reference &entry = store.get(ref); + enumerator.foreach_key([&store,this](const AtomicEntryRef& ref) + { const Reference &entry = store.get(ref.load_relaxed()); _referenceMappings.clearMapping(entry); }); incGeneration(); // Force freeze diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h index f985c799c07..a06aaf13247 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h @@ -26,6 +26,7 @@ namespace search::attribute { class ReferenceAttribute : public NotImplementedAttribute { public: + using AtomicEntryRef = vespalib::datastore::AtomicEntryRef; using CompactionStrategy = vespalib::datastore::CompactionStrategy; using EntryRef = vespalib::datastore::EntryRef; using GlobalId = document::GlobalId; diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.cpp index 1dfb49268bb..22d563def5c 100644 --- a/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.cpp @@ -8,6 +8,7 @@ using vespalib::GenerationHandler; using document::GlobalId; +using vespalib::datastore::AtomicEntryRef; using vespalib::datastore::EntryRef; namespace search { @@ -43,8 +44,8 @@ public: _writer(writer) { } - void operator()(EntryRef ref) { - const GlobalId &gid = _store.get(ref).gid(); + void operator()(const AtomicEntryRef& ref) { + const GlobalId &gid = _store.get(ref.load_acquire()).gid(); _writer.write(&gid, sizeof(GlobalId));; } }; diff --git a/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp b/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp index 7f279689985..aa2d060d20b 100644 --- a/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp +++ b/vespalib/src/tests/datastore/unique_store/unique_store_test.cpp @@ -416,7 +416,7 @@ TYPED_TEST(TestBase, store_can_be_enumerated) auto enumerator = this->getEnumerator(true); std::vector<uint32_t> refs; - enumerator.foreach_key([&](EntryRef ref) { refs.push_back(ref.ref()); }); + enumerator.foreach_key([&](const AtomicEntryRef& ref) { refs.push_back(ref.load_relaxed().ref()); }); std::vector<uint32_t> expRefs; expRefs.push_back(val0Ref.ref()); expRefs.push_back(val1Ref.ref()); diff --git a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp index 4a8b7eafe6a..d0fede5c550 100644 --- a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp +++ b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp @@ -113,7 +113,7 @@ TYPED_TEST(UniqueStoreDictionaryTest, can_iterate_all_keys) using EntryRefVector = std::vector<EntryRef>; this->add(3).add(5).add(7).take_snapshot(); EntryRefVector refs; - this->snapshot->foreach_key([&](EntryRef ref){ refs.emplace_back(ref); }); + this->snapshot->foreach_key([&](AtomicEntryRef ref){ refs.emplace_back(ref.load_relaxed()); }); EXPECT_EQ(EntryRefVector({EntryRef(3), EntryRef(5), EntryRef(7)}), refs); } @@ -161,7 +161,7 @@ TYPED_TEST(UniqueStoreDictionaryTest, compaction_works) } this->take_snapshot(); std::vector<EntryRef> refs; - this->snapshot->foreach_key([&](EntryRef ref){ refs.emplace_back(ref); }); + this->snapshot->foreach_key([&](const AtomicEntryRef& ref){ refs.emplace_back(ref.load_relaxed()); }); EXPECT_EQ(exp_refs, refs); } diff --git a/vespalib/src/vespa/vespalib/btree/btreeiterator.cpp b/vespalib/src/vespa/vespalib/btree/btreeiterator.cpp index 93e4a15b47d..8d451740177 100644 --- a/vespalib/src/vespa/vespalib/btree/btreeiterator.cpp +++ b/vespalib/src/vespa/vespalib/btree/btreeiterator.cpp @@ -7,7 +7,6 @@ namespace vespalib::btree { template class BTreeIteratorBase<uint32_t, uint32_t, NoAggregated>; template class BTreeIteratorBase<uint32_t, BTreeNoLeafData, NoAggregated>; -template class BTreeIteratorBase<datastore::EntryRef, BTreeNoLeafData, NoAggregated>; template class BTreeIteratorBase<uint32_t, int32_t, MinMaxAggregated>; template class BTreeConstIterator<uint32_t, uint32_t, NoAggregated>; template class BTreeConstIterator<uint32_t, BTreeNoLeafData, NoAggregated>; diff --git a/vespalib/src/vespa/vespalib/btree/btreeiterator.h b/vespalib/src/vespa/vespalib/btree/btreeiterator.h index 30123b1946e..e0df9744265 100644 --- a/vespalib/src/vespa/vespalib/btree/btreeiterator.h +++ b/vespalib/src/vespa/vespalib/btree/btreeiterator.h @@ -988,7 +988,6 @@ private: extern template class BTreeIteratorBase<uint32_t, uint32_t, NoAggregated>; extern template class BTreeIteratorBase<uint32_t, BTreeNoLeafData, NoAggregated>; -extern template class BTreeIteratorBase<datastore::EntryRef, BTreeNoLeafData, NoAggregated>; extern template class BTreeIteratorBase<uint32_t, int32_t, MinMaxAggregated>; extern template class BTreeConstIterator<uint32_t, uint32_t, NoAggregated>; extern template class BTreeConstIterator<uint32_t, BTreeNoLeafData, NoAggregated>; diff --git a/vespalib/src/vespa/vespalib/btree/btreenodestore.cpp b/vespalib/src/vespa/vespalib/btree/btreenodestore.cpp index e84d7eaf3ad..4787a1416de 100644 --- a/vespalib/src/vespa/vespalib/btree/btreenodestore.cpp +++ b/vespalib/src/vespa/vespalib/btree/btreenodestore.cpp @@ -36,13 +36,15 @@ VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(uint32_t, NoAggregated, B VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(uint32_t, MinMaxAggregated, BTreeDefaultTraits::INTERNAL_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(uint64_t, NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(uint64_t, MinMaxAggregated, BTreeDefaultTraits::INTERNAL_SLOTS); +VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(AtomicEntryRef, NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(EntryRef, NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(uint32_t, uint32_t, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(uint32_t, BTreeNoLeafData, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(uint32_t, int32_t , MinMaxAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(uint64_t, uint64_t , MinMaxAggregated, BTreeDefaultTraits::LEAF_SLOTS); -VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(EntryRef, uint32_t, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); +VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(AtomicEntryRef, uint32_t, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); +VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(AtomicEntryRef, BTreeNoLeafData, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(EntryRef, BTreeNoLeafData, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(EntryRef, EntryRef, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(uint32_t, EntryRef, NoAggregated, BTreeDefaultTraits::LEAF_SLOTS); diff --git a/vespalib/src/vespa/vespalib/datastore/CMakeLists.txt b/vespalib/src/vespa/vespalib/datastore/CMakeLists.txt index a2f7a4d4ff4..abbdc79c527 100644 --- a/vespalib/src/vespa/vespalib/datastore/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/datastore/CMakeLists.txt @@ -3,6 +3,7 @@ vespa_add_library(vespalib_vespalib_datastore OBJECT SOURCES array_store.cpp array_store_config.cpp + atomic_entry_ref.cpp buffer_type.cpp bufferstate.cpp compaction_strategy.cpp diff --git a/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.cpp b/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.cpp new file mode 100644 index 00000000000..b1504bb5aa3 --- /dev/null +++ b/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.cpp @@ -0,0 +1,12 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "atomic_entry_ref.h" +#include <vespa/vespalib/stllike/asciistream.h> + +namespace vespalib::datastore { + +vespalib::asciistream & operator << (vespalib::asciistream & os, const AtomicEntryRef &ref) { + return os << "AtomicEntryRef(" << ref.load_relaxed().ref() << ")"; +} + +} diff --git a/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.h b/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.h index 5fa83d41ad4..9866339f776 100644 --- a/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.h +++ b/vespalib/src/vespa/vespalib/datastore/atomic_entry_ref.h @@ -45,4 +45,6 @@ public: } }; +vespalib::asciistream& operator<<(vespalib::asciistream& os, const AtomicEntryRef& ref); + } diff --git a/vespalib/src/vespa/vespalib/datastore/entry_comparator_wrapper.h b/vespalib/src/vespa/vespalib/datastore/entry_comparator_wrapper.h index ee2e8d29cea..cc51f5ef732 100644 --- a/vespalib/src/vespa/vespalib/datastore/entry_comparator_wrapper.h +++ b/vespalib/src/vespa/vespalib/datastore/entry_comparator_wrapper.h @@ -15,8 +15,8 @@ public: EntryComparatorWrapper(const EntryComparator &comp) : _comp(comp) { } - bool operator()(const EntryRef &lhs, const EntryRef &rhs) const { - return _comp.less(lhs, rhs); + bool operator()(const AtomicEntryRef &lhs, const AtomicEntryRef &rhs) const { + return _comp.less(lhs.load_acquire(), rhs.load_acquire()); } }; diff --git a/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary_read_snapshot.h b/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary_read_snapshot.h index dc2187a843b..802547491bc 100644 --- a/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary_read_snapshot.h +++ b/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary_read_snapshot.h @@ -2,7 +2,7 @@ #pragma once -#include "entryref.h" +#include "atomic_entry_ref.h" #include <functional> namespace vespalib::datastore { @@ -21,7 +21,7 @@ public: virtual void sort() = 0; virtual size_t count(const EntryComparator& comp) const = 0; virtual size_t count_in_range(const EntryComparator& low, const EntryComparator& high) const = 0; - virtual void foreach_key(std::function<void(EntryRef)> callback) const = 0; + virtual void foreach_key(std::function<void(const AtomicEntryRef&)> callback) const = 0; }; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.cpp b/vespalib/src/vespa/vespalib/datastore/unique_store.cpp index dcd9b38fab8..bdaad5b9233 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store.cpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store.cpp @@ -7,7 +7,7 @@ namespace vespalib::datastore { using namespace btree; -VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(EntryRef, NoAggregated, uniquestore::DefaultDictionaryTraits::INTERNAL_SLOTS); -VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(EntryRef, BTreeNoLeafData, NoAggregated, uniquestore::DefaultDictionaryTraits::LEAF_SLOTS); +VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_INTERNALNODE(AtomicEntryRef, NoAggregated, uniquestore::DefaultDictionaryTraits::INTERNAL_SLOTS); +VESPALIB_DATASTORE_INSTANTIATE_BUFFERTYPE_LEAFNODE(AtomicEntryRef, BTreeNoLeafData, NoAggregated, uniquestore::DefaultDictionaryTraits::LEAF_SLOTS); } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp index b1a7db56545..a252763fb5b 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp @@ -18,7 +18,7 @@ namespace vespalib::datastore { namespace uniquestore { using DefaultDictionaryTraits = btree::BTreeTraits<32, 32, 7, true>; -using DefaultDictionary = btree::BTree<EntryRef, btree::BTreeNoLeafData, +using DefaultDictionary = btree::BTree<AtomicEntryRef, btree::BTreeNoLeafData, btree::NoAggregated, EntryComparatorWrapper, DefaultDictionaryTraits>; diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.h b/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.h index c9a57e545f8..b38c49ccab4 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.h @@ -24,7 +24,7 @@ public: void sort() override; size_t count(const EntryComparator& comp) const override; size_t count_in_range(const EntryComparator& low, const EntryComparator& high) const override; - void foreach_key(std::function<void(EntryRef)> callback) const override; + void foreach_key(std::function<void(const AtomicEntryRef&)> callback) const override; }; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.hpp index e2b05dcf481..b1ae0f3239c 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_btree_dictionary_read_snapshot.hpp @@ -28,8 +28,8 @@ template <typename BTreeDictionaryT> size_t UniqueStoreBTreeDictionaryReadSnapshot<BTreeDictionaryT>::count(const EntryComparator& comp) const { - auto itr = _frozen_view.lowerBound(EntryRef(), comp); - if (itr.valid() && !comp.less(EntryRef(), itr.getKey())) { + auto itr = _frozen_view.lowerBound(AtomicEntryRef(), comp); + if (itr.valid() && !comp.less(EntryRef(), itr.getKey().load_acquire())) { return 1u; } return 0u; @@ -39,17 +39,17 @@ template <typename BTreeDictionaryT> size_t UniqueStoreBTreeDictionaryReadSnapshot<BTreeDictionaryT>::count_in_range(const EntryComparator& low, const EntryComparator& high) const { - auto low_itr = _frozen_view.lowerBound(EntryRef(), low); + auto low_itr = _frozen_view.lowerBound(AtomicEntryRef(), low); auto high_itr = low_itr; - if (high_itr.valid() && !high.less(EntryRef(), high_itr.getKey())) { - high_itr.seekPast(EntryRef(), high); + if (high_itr.valid() && !high.less(EntryRef(), high_itr.getKey().load_acquire())) { + high_itr.seekPast(AtomicEntryRef(), high); } return high_itr - low_itr; } template <typename BTreeDictionaryT> void -UniqueStoreBTreeDictionaryReadSnapshot<BTreeDictionaryT>::foreach_key(std::function<void(EntryRef)> callback) const +UniqueStoreBTreeDictionaryReadSnapshot<BTreeDictionaryT>::foreach_key(std::function<void(const AtomicEntryRef&)> callback) const { _frozen_view.foreach_key(callback); } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp index 4375b38cf7c..bac65fc4cf8 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp @@ -70,16 +70,16 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::add(const Ent { if constexpr (has_btree_dictionary) { using DataType = typename BTreeDictionaryType::DataType; - auto itr = this->_btree_dict.lowerBound(EntryRef(), comp); - if (itr.valid() && !comp.less(EntryRef(), itr.getKey())) { + auto itr = this->_btree_dict.lowerBound(AtomicEntryRef(), comp); + if (itr.valid() && !comp.less(EntryRef(), itr.getKey().load_relaxed())) { if constexpr (has_hash_dictionary) { auto* result = this->_hash_dict.find(comp, EntryRef()); - assert(result != nullptr && result->first.load_relaxed() == itr.getKey()); + assert(result != nullptr && result->first.load_relaxed() == itr.getKey().load_relaxed()); } - return UniqueStoreAddResult(itr.getKey(), false); + return UniqueStoreAddResult(itr.getKey().load_relaxed(), false); } else { EntryRef newRef = insertEntry(); - this->_btree_dict.insert(itr, newRef, DataType()); + this->_btree_dict.insert(itr, AtomicEntryRef(newRef), DataType()); if constexpr (has_hash_dictionary) { std::function<EntryRef(void)> insert_hash_entry([newRef]() noexcept -> EntryRef { return newRef; }); auto& add_result = this->_hash_dict.add(comp, newRef, insert_hash_entry); @@ -102,13 +102,13 @@ EntryRef UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::find(const EntryComparator &comp) { if constexpr (has_btree_dictionary) { - auto itr = this->_btree_dict.lowerBound(EntryRef(), comp); - if (itr.valid() && !comp.less(EntryRef(), itr.getKey())) { + auto itr = this->_btree_dict.lowerBound(AtomicEntryRef(), comp); + if (itr.valid() && !comp.less(EntryRef(), itr.getKey().load_relaxed())) { if constexpr (has_hash_dictionary) { auto* result = this->_hash_dict.find(comp, EntryRef()); - assert(result != nullptr && result->first.load_relaxed() == itr.getKey()); + assert(result != nullptr && result->first.load_relaxed() == itr.getKey().load_relaxed()); } - return itr.getKey(); + return itr.getKey().load_relaxed(); } else { if constexpr (has_hash_dictionary) { auto* result = this->_hash_dict.find(comp, EntryRef()); @@ -128,8 +128,8 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::remove(const { assert(ref.valid()); if constexpr (has_btree_dictionary) { - auto itr = this->_btree_dict.lowerBound(ref, comp); - assert(itr.valid() && itr.getKey() == ref); + auto itr = this->_btree_dict.lowerBound(AtomicEntryRef(ref), comp); + assert(itr.valid() && itr.getKey().load_relaxed() == ref); this->_btree_dict.remove(itr); } if constexpr (has_hash_dictionary) { @@ -145,12 +145,12 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::move_keys(ICo if constexpr (has_btree_dictionary) { auto itr = this->_btree_dict.begin(); while (itr.valid()) { - EntryRef oldRef(itr.getKey()); + EntryRef oldRef(itr.getKey().load_relaxed()); assert(oldRef.valid()); if (compacting_buffers.has(oldRef)) { EntryRef newRef(compactable.move(oldRef)); this->_btree_dict.thaw(itr); - itr.writeKey(newRef); + itr.writeKey(AtomicEntryRef(newRef)); if constexpr (has_hash_dictionary) { auto result = this->_hash_dict.find(this->_hash_dict.get_default_comparator(), oldRef); assert(result != nullptr && result->first.load_relaxed() == oldRef); @@ -202,7 +202,7 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::build(vespali typename BTreeDictionaryType::Builder builder(this->_btree_dict.getAllocator()); for (size_t i = 1; i < refs.size(); ++i) { if (ref_counts[i] != 0u) { - builder.insert(refs[i], DataType()); + builder.insert(AtomicEntryRef(refs[i]), DataType()); } else { hold(refs[i]); } @@ -231,7 +231,7 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::build(vespali using DataType = typename BTreeDictionaryType::DataType; typename BTreeDictionaryType::Builder builder(this->_btree_dict.getAllocator()); for (const auto& ref : refs) { - builder.insert(ref, DataType()); + builder.insert(AtomicEntryRef(ref), DataType()); } this->_btree_dict.assign(builder); } @@ -255,9 +255,9 @@ UniqueStoreDictionary<BTreeDictionaryT, ParentT, HashDictionaryT>::build_with_pa typename BTreeDictionaryType::Builder builder(this->_btree_dict.getAllocator()); for (size_t i = 0; i < refs.size(); ++i) { if constexpr (std::is_same_v<DataType, uint32_t>) { - builder.insert(refs[i], payloads[i]); - } else { - builder.insert(refs[i], DataType()); + builder.insert(AtomicEntryRef(refs[i]), payloads[i]); + } else { + builder.insert(AtomicEntryRef(refs[i]), DataType()); } } this->_btree_dict.assign(builder); diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp index ec3b0c54bda..214f5b8e8c4 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp @@ -56,7 +56,7 @@ void UniqueStoreEnumerator<RefT>::enumerateValues() { _next_enum_val = 1; - _dict_snapshot->foreach_key([this](EntryRef ref) noexcept { enumerateValue(ref); }); + _dict_snapshot->foreach_key([this](const AtomicEntryRef& ref) noexcept { enumerateValue(ref.load_acquire()); }); } template <typename RefT> diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.h b/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.h index 3a3aeb7ab64..e5a7bbe62c6 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.h @@ -28,7 +28,7 @@ public: void sort() override; size_t count(const EntryComparator& comp) const override; size_t count_in_range(const EntryComparator& low, const EntryComparator& high) const override; - void foreach_key(std::function<void(EntryRef)> callback) const override; + void foreach_key(std::function<void(const AtomicEntryRef&)> callback) const override; }; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.hpp index 302336f462c..7b68373aa3a 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_hash_dictionary_read_snapshot.hpp @@ -45,10 +45,10 @@ UniqueStoreHashDictionaryReadSnapshot<HashDictionaryT>::count_in_range(const Ent template <typename HashDictionaryT> void -UniqueStoreHashDictionaryReadSnapshot<HashDictionaryT>::foreach_key(std::function<void(EntryRef)> callback) const +UniqueStoreHashDictionaryReadSnapshot<HashDictionaryT>::foreach_key(std::function<void(const AtomicEntryRef&)> callback) const { for (auto ref : _refs) { - callback(ref); + callback(AtomicEntryRef(ref)); } } |