summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2024-02-15 13:21:11 +0100
committerTor Egge <Tor.Egge@online.no>2024-02-15 13:21:11 +0100
commitfe310e5cdfe5e51abddda0a8ed6ef100ae11ccfb (patch)
tree602cef16199c5c63eedc36cdde3829188fa57185
parentfe7cfe2a7c6c549acedd217f73fa4fc6340c81eb (diff)
Prepare SimpleIndexSaver for index flush thread.
-rw-r--r--searchlib/src/vespa/searchlib/predicate/simple_index.hpp14
-rw-r--r--searchlib/src/vespa/searchlib/predicate/simple_index_saver.h12
-rw-r--r--searchlib/src/vespa/searchlib/predicate/simple_index_saver.hpp39
3 files changed, 51 insertions, 14 deletions
diff --git a/searchlib/src/vespa/searchlib/predicate/simple_index.hpp b/searchlib/src/vespa/searchlib/predicate/simple_index.hpp
index 5c5afedfe90..5d2380b523d 100644
--- a/searchlib/src/vespa/searchlib/predicate/simple_index.hpp
+++ b/searchlib/src/vespa/searchlib/predicate/simple_index.hpp
@@ -108,18 +108,18 @@ SimpleIndex<Posting, Key, DocId>::deserialize(vespalib::DataBuffer &buffer, Post
template <typename Posting, typename Key, typename DocId>
void
SimpleIndex<Posting, Key, DocId>::addPosting(Key key, DocId doc_id, const Posting &posting) {
- auto iter = _dictionary.find(key);
+ auto iter = _dictionary.lowerBound(key);
vespalib::datastore::EntryRef ref;
- if (iter.valid()) {
+ if (iter.valid() && key == iter.getKey()) {
ref = iter.getData();
insertIntoPosting(ref, key, doc_id, posting);
if (ref != iter.getData()) {
- std::atomic_thread_fence(std::memory_order_release);
+ _dictionary.thaw(iter);
iter.writeData(ref);
}
} else {
insertIntoPosting(ref, key, doc_id, posting);
- _dictionary.insert(key, ref);
+ _dictionary.insert(iter, key, ref);
}
}
@@ -147,9 +147,9 @@ SimpleIndex<Posting, Key, DocId>::removeFromPostingList(Key key, DocId doc_id) {
_btree_posting_lists.remove(ref, doc_id);
removeFromVectorPostingList(ref, key, doc_id);
if (!ref.valid()) { // last posting was removed
- _dictionary.remove(key);
+ _dictionary.remove(dict_it);
} else if (ref != original_ref) { // ref changed. update dictionary.
- std::atomic_thread_fence(std::memory_order_release);
+ _dictionary.thaw(dict_it);
dict_it.writeData(ref);
}
return std::make_pair(posting, true);
@@ -304,7 +304,7 @@ template <typename Posting, typename Key, typename DocId>
std::unique_ptr<ISaver>
SimpleIndex<Posting, Key, DocId>::make_saver(std::unique_ptr<PostingSaver<Posting>> subsaver) const
{
- return std::make_unique<SimpleIndexSaver<Posting, Key, DocId>>(_dictionary, _btree_posting_lists, std::move(subsaver));
+ return std::make_unique<SimpleIndexSaver<Posting, Key, DocId>>(_dictionary.getFrozenView(), _btree_posting_lists, std::move(subsaver));
}
}
diff --git a/searchlib/src/vespa/searchlib/predicate/simple_index_saver.h b/searchlib/src/vespa/searchlib/predicate/simple_index_saver.h
index eefaf7c79f4..53357187d54 100644
--- a/searchlib/src/vespa/searchlib/predicate/simple_index_saver.h
+++ b/searchlib/src/vespa/searchlib/predicate/simple_index_saver.h
@@ -4,6 +4,7 @@
#include "i_saver.h"
#include "simple_index.h"
+#include <vespa/vespalib/stllike/allocator.h>
namespace search::predicate {
@@ -15,15 +16,20 @@ template <typename Posting,
typename Key = uint64_t, typename DocId = uint32_t>
class SimpleIndexSaver : public ISaver
{
+ using EntryRef = vespalib::datastore::EntryRef;
using Source = SimpleIndex<Posting,Key,DocId>;
- using Dictionary = Source::Dictionary;
+ using Dictionary = Source::Dictionary::FrozenView;
+ using FrozenRoots = std::vector<EntryRef, vespalib::allocator_large<EntryRef>>;
using BTreeStore = Source::BTreeStore;
- const Dictionary& _dictionary;
+ const Dictionary _dictionary;
+ FrozenRoots _frozen_roots;
const BTreeStore& _btree_posting_lists;
std::unique_ptr<PostingSaver<Posting>> _subsaver;
+
+ void make_frozen_roots();
public:
- SimpleIndexSaver(const Dictionary& dictionary, const BTreeStore& btree_posting_lists, std::unique_ptr<PostingSaver<Posting>> _subsaver);
+ SimpleIndexSaver(Dictionary dictionary, const BTreeStore& btree_posting_lists, std::unique_ptr<PostingSaver<Posting>> _subsaver);
~SimpleIndexSaver() override;
void save(BufferWriter& writer) const override;
};
diff --git a/searchlib/src/vespa/searchlib/predicate/simple_index_saver.hpp b/searchlib/src/vespa/searchlib/predicate/simple_index_saver.hpp
index a3db21ca6cb..327d5440346 100644
--- a/searchlib/src/vespa/searchlib/predicate/simple_index_saver.hpp
+++ b/searchlib/src/vespa/searchlib/predicate/simple_index_saver.hpp
@@ -6,11 +6,13 @@
namespace search::predicate {
template <typename Posting, typename Key, typename DocId>
-SimpleIndexSaver<Posting, Key, DocId>::SimpleIndexSaver(const Dictionary& dictionary, const BTreeStore& btree_posting_lists, std::unique_ptr<PostingSaver<Posting>> subsaver)
- : _dictionary(dictionary),
+SimpleIndexSaver<Posting, Key, DocId>::SimpleIndexSaver(Dictionary dictionary, const BTreeStore& btree_posting_lists, std::unique_ptr<PostingSaver<Posting>> subsaver)
+ : _dictionary(std::move(dictionary)),
+ _frozen_roots(),
_btree_posting_lists(btree_posting_lists),
_subsaver(std::move(subsaver))
{
+ make_frozen_roots();
}
template <typename Posting, typename Key, typename DocId>
@@ -23,9 +25,16 @@ SimpleIndexSaver<Posting, Key, DocId>::save(BufferWriter& writer) const
assert(sizeof(Key) <= sizeof(uint64_t));
assert(sizeof(DocId) <= sizeof(uint32_t));
nbo_write<uint32_t>(writer, _dictionary.size());
- for (auto it = _dictionary.begin(); it.valid(); ++it) {
+ auto& allocator = _btree_posting_lists.getAllocator();
+ auto frozen_roots_it = _frozen_roots.begin();
+ using PostingIterator = BTreeStore::ConstIterator;
+ for (auto it = _dictionary.begin(); it.valid(); ++it, ++frozen_roots_it) {
vespalib::datastore::EntryRef ref = it.getData();
- auto posting_it = _btree_posting_lists.begin(ref);
+ /*
+ * Use copy of frozen root if valid, otherwise use ref from
+ * frozen dictionary.
+ */
+ auto posting_it = frozen_roots_it->valid() ? PostingIterator(*frozen_roots_it, allocator) : _btree_posting_lists.begin(ref);
nbo_write<uint32_t>(writer, posting_it.size()); // 0 if !valid()
if (!posting_it.valid())
continue;
@@ -35,6 +44,28 @@ SimpleIndexSaver<Posting, Key, DocId>::save(BufferWriter& writer) const
_subsaver->save(posting_it.getData(), writer);
}
}
+ assert(frozen_roots_it == _frozen_roots.end());
+}
+
+template <typename Posting, typename Key, typename DocId>
+void
+SimpleIndexSaver<Posting, Key, DocId>::make_frozen_roots()
+{
+ /*
+ * Compensate for lacking snapshot property in
+ * vespalib::btree::BTreeStore. Traverse frozen dictionary in writer
+ * thread and make a copy of frozen btree roots.
+ */
+ _frozen_roots.reserve(_dictionary.size());
+ for (auto it = _dictionary.begin(); it.valid(); ++it) {
+ auto ref = it.getData();
+ if (ref.valid() && _btree_posting_lists.isBTree(ref)) {
+ _frozen_roots.emplace_back(_btree_posting_lists.getTreeEntry(ref)->getFrozenRootRelaxed());
+ assert(_frozen_roots.back().valid());
+ } else {
+ _frozen_roots.emplace_back();
+ }
+ }
}
}