aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2023-09-18 14:39:40 +0200
committerTor Egge <Tor.Egge@online.no>2023-09-18 14:39:40 +0200
commitf2f4479ae174233da0deb382760ba5201ccf9223 (patch)
treed06a1d5f73749dcfcc310a7d0fbb5b0066761e36
parent5e5137cf0ab9cc67452f36b488394458f827b2b0 (diff)
Use make_for_lookup() member function on existing comparator
to make a new comparator which is used for lookup.
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumcomparator.h33
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.h17
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.hpp12
-rw-r--r--vespalib/src/tests/datastore/fixed_size_hash_map/fixed_size_hash_map_test.cpp14
-rw-r--r--vespalib/src/tests/datastore/sharded_hash_map/sharded_hash_map_test.cpp18
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store.hpp4
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h8
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_string_comparator.h16
8 files changed, 71 insertions, 51 deletions
diff --git a/searchlib/src/vespa/searchlib/attribute/enumcomparator.h b/searchlib/src/vespa/searchlib/attribute/enumcomparator.h
index 52d9ebad902..255719ad1c1 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumcomparator.h
+++ b/searchlib/src/vespa/searchlib/attribute/enumcomparator.h
@@ -18,14 +18,24 @@ public:
using ParentType = vespalib::datastore::UniqueStoreComparator<EntryT, IEnumStore::InternalIndex>;
using DataStoreType = typename ParentType::DataStoreType;
- EnumStoreComparator(const DataStoreType& data_store, const EntryT& lookup_value)
- : ParentType(data_store, lookup_value)
- {}
EnumStoreComparator(const DataStoreType& data_store)
: ParentType(data_store)
{}
+private:
+ EnumStoreComparator(const DataStoreType& data_store, const EntryT& lookup_value)
+ : ParentType(data_store, lookup_value)
+ {}
+
+public:
static bool equal_helper(const EntryT& lhs, const EntryT& rhs);
+
+ EnumStoreComparator<EntryT> make_folded() const {
+ return *this;
+ }
+ EnumStoreComparator<EntryT> make_for_lookup(const EntryT& lookup_value) const {
+ return EnumStoreComparator<EntryT>(this->_store, lookup_value);
+ }
};
/**
@@ -45,22 +55,31 @@ public:
EnumStoreStringComparator(const DataStoreType& data_store)
: EnumStoreStringComparator(data_store, false)
{}
+
+private:
EnumStoreStringComparator(const DataStoreType& data_store, bool fold);
/**
* Creates a comparator using the given low-level data store and that uses the
* given value during compare if the enum index is invalid.
*/
- EnumStoreStringComparator(const DataStoreType& data_store, const char* lookup_value)
- : EnumStoreStringComparator(data_store, false, lookup_value)
- {}
EnumStoreStringComparator(const DataStoreType& data_store, bool fold, const char* lookup_value);
EnumStoreStringComparator(const DataStoreType& data_store, bool fold, const char* lookup_value, bool prefix);
+public:
bool less(const vespalib::datastore::EntryRef lhs, const vespalib::datastore::EntryRef rhs) const override;
bool equal(const vespalib::datastore::EntryRef lhs, const vespalib::datastore::EntryRef rhs) const override;
+ EnumStoreStringComparator make_folded() const {
+ return EnumStoreStringComparator(_store, true);
+ }
+ EnumStoreStringComparator make_for_lookup(const char* lookup_value) const {
+ return EnumStoreStringComparator(_store, _fold, lookup_value);
+ }
+ EnumStoreStringComparator make_for_prefix_lookup(const char* lookup_value) const {
+ return EnumStoreStringComparator(_store, _fold, lookup_value, true);
+ }
private:
- inline bool use_prefix() const { return _prefix; }
+ inline bool use_prefix() const noexcept { return _prefix; }
const bool _fold;
const bool _prefix;
uint32_t _prefix_len;
diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.h b/searchlib/src/vespa/searchlib/attribute/enumstore.h
index 8cafd04586e..6560decf42f 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumstore.h
+++ b/searchlib/src/vespa/searchlib/attribute/enumstore.h
@@ -37,15 +37,16 @@ namespace search {
template <class EntryT>
class EnumStoreT : public IEnumStore {
public:
- using ComparatorType = std::conditional_t<std::is_same_v<EntryT, const char *>,
+ using EntryType = EntryT;
+ static constexpr bool has_string_type = std::is_same_v<EntryType, const char *>;
+ using ComparatorType = std::conditional_t<has_string_type,
EnumStoreStringComparator,
EnumStoreComparator<EntryT>>;
- using AllocatorType = std::conditional_t<std::is_same_v<EntryT, const char *>,
+ using AllocatorType = std::conditional_t<has_string_type,
vespalib::datastore::UniqueStoreStringAllocator<InternalIndex>,
vespalib::datastore::UniqueStoreAllocator<EntryT, InternalIndex>>;
using UniqueStoreType = vespalib::datastore::UniqueStore<EntryT, InternalIndex, ComparatorType, AllocatorType>;
- using EntryType = EntryT;
using EnumStoreType = EnumStoreT<EntryT>;
using EntryRef = vespalib::datastore::EntryRef;
using EntryComparator = vespalib::datastore::EntryComparator;
@@ -69,10 +70,6 @@ private:
return _store.get_allocator().get_wrapped(idx);
}
- static bool has_string_type() {
- return std::is_same_v<EntryType, const char *>;
- }
-
ssize_t load_unique_values_internal(const void* src, size_t available, IndexVector& idx);
ssize_t load_unique_value(const void* src, size_t available, Index& idx);
@@ -191,7 +188,7 @@ public:
}
ComparatorType make_comparator(const EntryType& lookup_value) const {
- return ComparatorType(_store.get_data_store(), lookup_value);
+ return _store.get_comparator().make_for_lookup(lookup_value);
}
const EntryComparator & get_folded_comparator() const {
@@ -225,12 +222,12 @@ public:
template <typename Type>
ComparatorType
make_folded_comparator(const Type& lookup_value) const {
- return ComparatorType(_store.get_data_store(), is_folded(), lookup_value);
+ return _foldedComparator.make_for_lookup(lookup_value);
}
template<typename Type>
ComparatorType
make_folded_comparator_prefix(const Type& lookup_value) const {
- return ComparatorType(_store.get_data_store(), is_folded(), lookup_value, true);
+ return _foldedComparator.make_for_prefix_lookup(lookup_value);
}
template<typename Type>
std::vector<IEnumStore::EnumHandle>
diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
index 85cf676182e..140ac207d32 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
@@ -305,15 +305,15 @@ template <typename EntryT>
std::unique_ptr<EntryComparator>
EnumStoreT<EntryT>::allocate_comparator() const
{
- return std::make_unique<ComparatorType>(_store.get_data_store());
+ return std::make_unique<ComparatorType>(_store.get_comparator());
}
template <typename EntryT>
std::unique_ptr<EntryComparator>
EnumStoreT<EntryT>::allocate_optionally_folded_comparator(bool folded) const
{
- return (has_string_type() && folded)
- ? std::make_unique<ComparatorType>(_store.get_data_store(), true)
+ return (has_string_type && folded)
+ ? std::make_unique<ComparatorType>(_store.get_comparator().make_folded())
: std::unique_ptr<EntryComparator>();
}
@@ -321,9 +321,9 @@ template <typename EntryT>
typename EnumStoreT<EntryT>::ComparatorType
EnumStoreT<EntryT>::make_optionally_folded_comparator(bool folded) const
{
- return (has_string_type() && folded)
- ? ComparatorType(_store.get_data_store(), true)
- : ComparatorType(_store.get_data_store());
+ return (has_string_type && folded)
+ ? _store.get_comparator().make_folded()
+ : _store.get_comparator();
}
}
diff --git a/vespalib/src/tests/datastore/fixed_size_hash_map/fixed_size_hash_map_test.cpp b/vespalib/src/tests/datastore/fixed_size_hash_map/fixed_size_hash_map_test.cpp
index 4f4c3ac94eb..58fd5b4c356 100644
--- a/vespalib/src/tests/datastore/fixed_size_hash_map/fixed_size_hash_map_test.cpp
+++ b/vespalib/src/tests/datastore/fixed_size_hash_map/fixed_size_hash_map_test.cpp
@@ -20,7 +20,7 @@ using vespalib::datastore::EntryRef;
using RefT = vespalib::datastore::EntryRefT<22>;
using MyAllocator = vespalib::datastore::UniqueStoreAllocator<uint32_t, RefT>;
using MyDataStore = vespalib::datastore::DataStoreT<RefT>;
-using MyCompare = vespalib::datastore::UniqueStoreComparator<uint32_t, RefT>;
+using MyComparator = vespalib::datastore::UniqueStoreComparator<uint32_t, RefT>;
using GenerationHandler = vespalib::GenerationHandler;
using vespalib::makeLambdaTask;
using vespalib::GenerationHolder;
@@ -48,7 +48,7 @@ struct DataStoreFixedSizeHashTest : public ::testing::Test
GenerationHolder _generation_holder;
MyAllocator _allocator;
MyDataStore& _store;
- std::unique_ptr<const vespalib::datastore::EntryComparator> _comp;
+ const MyComparator _comparator;
std::unique_ptr<FixedSizeHashMap> _hash_map;
vespalib::Rand48 _rnd;
@@ -70,7 +70,7 @@ DataStoreFixedSizeHashTest::DataStoreFixedSizeHashTest()
_generation_holder(),
_allocator({}),
_store(_allocator.get_data_store()),
- _comp(std::make_unique<MyCompare>(_store)),
+ _comparator(_store),
_hash_map(),
_rnd()
{
@@ -106,7 +106,7 @@ DataStoreFixedSizeHashTest::size() const noexcept
void
DataStoreFixedSizeHashTest::insert(uint32_t key)
{
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
std::function<EntryRef(void)> insert_entry([this, key]() -> EntryRef { return _allocator.allocate(key); });
auto& result = _hash_map->add(_hash_map->get_comp(comp), insert_entry);
auto ref = result.first.load_relaxed();
@@ -117,7 +117,7 @@ DataStoreFixedSizeHashTest::insert(uint32_t key)
void
DataStoreFixedSizeHashTest::remove(uint32_t key)
{
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
auto result = _hash_map->remove(_hash_map->get_comp(comp));
if (result != nullptr) {
auto ref = result->first.load_relaxed();
@@ -130,7 +130,7 @@ DataStoreFixedSizeHashTest::remove(uint32_t key)
bool
DataStoreFixedSizeHashTest::has_key(uint32_t key)
{
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
auto result = _hash_map->find(_hash_map->get_comp(comp));
if (result != nullptr) {
auto ref = result->first.load_relaxed();
@@ -270,7 +270,7 @@ TEST_F(DataStoreFixedSizeHashTest, lookups_works_after_insert_and_remove)
commit();
}
for (auto &kv : expected) {
- MyCompare comp(_store, kv.first);
+ auto comp = _comparator.make_for_lookup(kv.first);
EXPECT_EQ(kv.second, _hash_map->find(_hash_map->get_comp(comp)) != nullptr);
}
}
diff --git a/vespalib/src/tests/datastore/sharded_hash_map/sharded_hash_map_test.cpp b/vespalib/src/tests/datastore/sharded_hash_map/sharded_hash_map_test.cpp
index eec3a6e6188..9c2369dea08 100644
--- a/vespalib/src/tests/datastore/sharded_hash_map/sharded_hash_map_test.cpp
+++ b/vespalib/src/tests/datastore/sharded_hash_map/sharded_hash_map_test.cpp
@@ -25,7 +25,7 @@ using vespalib::datastore::ICompactable;
using RefT = vespalib::datastore::EntryRefT<22>;
using MyAllocator = vespalib::datastore::UniqueStoreAllocator<uint32_t, RefT>;
using MyDataStore = vespalib::datastore::DataStoreT<RefT>;
-using MyCompare = vespalib::datastore::UniqueStoreComparator<uint32_t, RefT>;
+using MyComparator = vespalib::datastore::UniqueStoreComparator<uint32_t, RefT>;
using MyHashMap = vespalib::datastore::ShardedHashMap;
using GenerationHandler = vespalib::GenerationHandler;
using vespalib::makeLambdaTask;
@@ -101,6 +101,7 @@ struct DataStoreShardedHashTest : public ::testing::Test
GenerationHandler _generationHandler;
MyAllocator _allocator;
MyDataStore& _store;
+ const MyComparator _comparator;
MyHashMap _hash_map;
vespalib::ThreadStackExecutor _writer; // 1 write thread
vespalib::ThreadStackExecutor _readers; // multiple reader threads
@@ -134,7 +135,8 @@ DataStoreShardedHashTest::DataStoreShardedHashTest()
: _generationHandler(),
_allocator({}),
_store(_allocator.get_data_store()),
- _hash_map(std::make_unique<MyCompare>(_store)),
+ _comparator(_store),
+ _hash_map(std::make_unique<MyComparator>(_comparator)),
_writer(1),
_readers(4),
_rnd(),
@@ -178,7 +180,7 @@ DataStoreShardedHashTest::commit()
void
DataStoreShardedHashTest::insert(uint32_t key)
{
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
std::function<EntryRef(void)> insert_entry([this, key]() -> EntryRef { return _allocator.allocate(key); });
auto& result = _hash_map.add(comp, EntryRef(), insert_entry);
auto ref = result.first.load_relaxed();
@@ -189,7 +191,7 @@ DataStoreShardedHashTest::insert(uint32_t key)
void
DataStoreShardedHashTest::remove(uint32_t key)
{
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
auto result = _hash_map.remove(comp, EntryRef());
if (result != nullptr) {
auto ref = result->first.load_relaxed();
@@ -210,7 +212,7 @@ DataStoreShardedHashTest::read_work(uint32_t cnt)
for (i = 0; i < cnt && _stop_read.load() == 0; ++i) {
auto guard = _generationHandler.takeGuard();
uint32_t key = rnd.lrand48() % (_keyLimit + 1);
- MyCompare comp(_store, key);
+ auto comp = _comparator.make_for_lookup(key);
auto result = _hash_map.find(comp, EntryRef());
if (result != nullptr) {
auto ref = result->first.load_relaxed();
@@ -264,7 +266,7 @@ void
DataStoreShardedHashTest::populate_sample_values(uint32_t cnt)
{
for (uint32_t i = 0; i < cnt; ++i) {
- MyCompare comp(_store, i);
+ auto comp = _comparator.make_for_lookup(i);
auto result = _hash_map.find(comp, EntryRef());
ASSERT_NE(result, nullptr);
EXPECT_EQ(i, _allocator.get_wrapped(result->first.load_relaxed()).value());
@@ -276,7 +278,7 @@ void
DataStoreShardedHashTest::clear_sample_values(uint32_t cnt)
{
for (uint32_t i = 0; i < cnt; ++i) {
- MyCompare comp(_store, i);
+ auto comp = _comparator.make_for_lookup(i);
auto result = _hash_map.find(comp, EntryRef());
ASSERT_NE(result, nullptr);
EXPECT_EQ(i, _allocator.get_wrapped(result->first.load_relaxed()).value());
@@ -312,7 +314,7 @@ DataStoreShardedHashTest::test_normalize_values(bool use_filter, bool one_filter
EXPECT_TRUE(_hash_map.normalize_values([](EntryRef ref) noexcept { RefT iref(ref); return RefT(iref.offset() + 300, iref.bufferId()); }));
}
for (uint32_t i = 0; i < large_population; ++i) {
- MyCompare comp(_store, i);
+ auto comp = _comparator.make_for_lookup(i);
auto result = _hash_map.find(comp, EntryRef());
ASSERT_NE(result, nullptr);
EXPECT_EQ(i, _allocator.get_wrapped(result->first.load_relaxed()).value());
diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
index fc912382cf8..d197af92fd9 100644
--- a/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
+++ b/vespalib/src/vespa/vespalib/datastore/unique_store.hpp
@@ -50,7 +50,7 @@ template <typename EntryT, typename RefT, typename Comparator, typename Allocato
UniqueStoreAddResult
UniqueStore<EntryT, RefT, Comparator, Allocator>::add(EntryConstRefType value)
{
- Comparator comp(_store, value);
+ auto comp = _comparator.make_for_lookup(value);
UniqueStoreAddResult result = _dict->add(comp, [this, &value]() -> EntryRef { return _allocator.allocate(value); });
_allocator.get_wrapped(result.ref()).inc_ref_count();
return result;
@@ -60,7 +60,7 @@ template <typename EntryT, typename RefT, typename Comparator, typename Allocato
EntryRef
UniqueStore<EntryT, RefT, Comparator, Allocator>::find(EntryConstRefType value)
{
- Comparator comp(_store, value);
+ auto comp = _comparator.make_for_lookup(value);
return _dict->find(comp);
}
diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h b/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h
index 38ae8c0c442..b238b42c54e 100644
--- a/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h
+++ b/vespalib/src/vespa/vespalib/datastore/unique_store_comparator.h
@@ -106,14 +106,12 @@ protected:
return _lookup_value;
}
}
-
-public:
UniqueStoreComparator(const DataStoreType &store, const EntryType &lookup_value)
: _store(store),
_lookup_value(lookup_value)
{
}
-
+public:
UniqueStoreComparator(const DataStoreType &store)
: _store(store),
_lookup_value()
@@ -134,6 +132,10 @@ public:
const EntryType &rhsValue = get(rhs);
return UniqueStoreComparatorHelper<EntryT>::hash(rhsValue);
}
+
+ UniqueStoreComparator<EntryT, RefT> make_for_lookup(const EntryType& lookup_value) const {
+ return UniqueStoreComparator<EntryT, RefT>(_store, lookup_value);
+ }
};
}
diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_string_comparator.h b/vespalib/src/vespa/vespalib/datastore/unique_store_string_comparator.h
index 4ce9923b549..afdbf4b31fa 100644
--- a/vespalib/src/vespa/vespalib/datastore/unique_store_string_comparator.h
+++ b/vespalib/src/vespa/vespalib/datastore/unique_store_string_comparator.h
@@ -37,20 +37,17 @@ protected:
return _lookup_value;
}
}
-
-public:
- UniqueStoreStringComparator(const DataStoreType &store)
+ UniqueStoreStringComparator(const DataStoreType &store, const char *lookup_value)
: _store(store),
- _lookup_value(nullptr)
+ _lookup_value(lookup_value)
{
}
-
- UniqueStoreStringComparator(const DataStoreType &store, const char *lookup_value)
+public:
+ UniqueStoreStringComparator(const DataStoreType &store)
: _store(store),
- _lookup_value(lookup_value)
+ _lookup_value(nullptr)
{
}
-
bool less(const EntryRef lhs, const EntryRef rhs) const override {
const char *lhs_value = get(lhs);
const char *rhs_value = get(rhs);
@@ -66,6 +63,9 @@ public:
vespalib::hash<const char *> hasher;
return hasher(rhs_value);
}
+ UniqueStoreStringComparator<RefT> make_for_lookup(const char* lookup_value) const {
+ return UniqueStoreStringComparator<RefT>(_store, lookup_value);
+ }
};
}