aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2024-04-25 12:18:20 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2024-04-25 12:18:20 +0000
commit34d83ef767f1e9378395e87d55617878ef150f38 (patch)
treec7dda0244551fad398e837c9540efa2f57f993e0
parentf4207b32a6a64549408d63fb09326634370326c3 (diff)
Use non_existing_attribute_value to signal that value is the default value for an attribute that has not been set.
-rw-r--r--eval/src/vespa/eval/eval/typed_cells.h17
-rw-r--r--searchlib/src/tests/attribute/extendattributes/extendattribute_test.cpp2
-rw-r--r--searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp13
-rw-r--r--searchlib/src/vespa/searchlib/tensor/distance_calculator.h4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/empty_subspace.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp4
6 files changed, 31 insertions, 13 deletions
diff --git a/eval/src/vespa/eval/eval/typed_cells.h b/eval/src/vespa/eval/eval/typed_cells.h
index 3dd8c30a3a9..7aa7debff30 100644
--- a/eval/src/vespa/eval/eval/typed_cells.h
+++ b/eval/src/vespa/eval/eval/typed_cells.h
@@ -11,7 +11,8 @@ namespace vespalib::eval {
struct TypedCells {
const void *data;
- size_t size:56;
+ size_t size:55;
+ bool _non_existing_attribute_value:1;
CellType type;
explicit TypedCells(ConstArrayRef<double> cells) noexcept : data(cells.begin()), size(cells.size()), type(CellType::DOUBLE) {}
@@ -22,6 +23,12 @@ struct TypedCells {
TypedCells() noexcept : data(nullptr), size(0), type(CellType::DOUBLE) {}
TypedCells(const void *dp, CellType ct, size_t sz) noexcept : data(dp), size(sz), type(ct) {}
+ static TypedCells create_non_existing_attribute_value(const void *dp, CellType ct, size_t sz) {
+ TypedCells cells(dp, ct, sz);
+ cells._non_existing_attribute_value = true;
+ return cells;
+ }
+
template <typename T> bool check_type() const noexcept { return check_cell_type<T>(type); }
template <typename T> ConstArrayRef<T> typify() const noexcept {
@@ -36,7 +43,13 @@ struct TypedCells {
TypedCells(const TypedCells &other) noexcept = default;
TypedCells & operator= (TypedCells &&other) noexcept = default;
TypedCells & operator= (const TypedCells &other) noexcept = default;
- bool valid() const noexcept { return size != 0; }
+ /**
+ * This signals that this actually points to a value that is the default value
+ * when no value has set for the attribute.
+ * TODO: This does not belong here, but as it is used as an interface multiple places it must be so
+ * until we come up with a better solution.
+ */
+ bool non_existing_attribute_value() const noexcept { return _non_existing_attribute_value; }
};
} // namespace
diff --git a/searchlib/src/tests/attribute/extendattributes/extendattribute_test.cpp b/searchlib/src/tests/attribute/extendattributes/extendattribute_test.cpp
index d67757a3811..0c60b376361 100644
--- a/searchlib/src/tests/attribute/extendattributes/extendattribute_test.cpp
+++ b/searchlib/src/tests/attribute/extendattributes/extendattribute_test.cpp
@@ -224,7 +224,7 @@ void ExtendAttributeTest::testExtendRaw(AttributeVector& attr)
void ExtendAttributeTest::testExtendTensor(AttributeVector& attr)
{
- std::vector<double> empty_cells{};
+ std::vector<double> empty_cells{0, 0};
std::vector<double> spec0_dense_cells{1.0, 2.0};
std::vector<double> spec0_mixed_cells0{3.0, 4.0};
std::vector<double> spec0_mixed_cells1{5.0, 6.0};
diff --git a/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp b/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp
index 31b147c0b5c..d50677314df 100644
--- a/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp
+++ b/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp
@@ -12,6 +12,7 @@
#include <vespa/searchlib/tensor/random_level_generator.h>
#include <vespa/searchlib/tensor/inv_log_level_generator.h>
#include <vespa/searchlib/tensor/subspace_type.h>
+#include <vespa/searchlib/tensor/empty_subspace.h>
#include <vespa/searchlib/tensor/vector_bundle.h>
#include <vespa/searchlib/queryeval/global_filter.h>
#include <vespa/vespalib/datastore/compaction_spec.h>
@@ -49,6 +50,7 @@ private:
using ArrayRef = vespalib::ConstArrayRef<FloatType>;
mutable std::vector<Vector> _vectors;
SubspaceType _subspace_type;
+ EmptySubspace _empty;
mutable uint32_t _get_vector_count;
mutable uint32_t _schedule_clear_tensor;
mutable uint32_t _cleared_tensor_docid;
@@ -57,6 +59,7 @@ public:
MyDocVectorAccess()
: _vectors(),
_subspace_type(ValueType::make_type(get_cell_type<FloatType>(), {{"dims", 2}})),
+ _empty(_subspace_type),
_get_vector_count(0),
_schedule_clear_tensor(0),
_cleared_tensor_docid(0)
@@ -87,7 +90,7 @@ public:
if (subspace < bundle.subspaces()) {
return bundle.cells(subspace);
}
- return { nullptr, _subspace_type.cell_type(), 0 };
+ return _empty.cells();
}
VectorBundle get_vectors(uint32_t docid) const noexcept override {
ArrayRef ref(_vectors[docid]);
@@ -128,12 +131,12 @@ public:
double min_rawscore() const noexcept override { return _real->min_rawscore(); }
double calc(TypedCells rhs) const noexcept override {
- EXPECT_TRUE(rhs.valid());
+ EXPECT_FALSE(rhs.non_existing_attribute_value());
return _real->calc(rhs);
}
double calc_with_limit(TypedCells rhs, double limit) const noexcept override {
- EXPECT_TRUE(rhs.valid());
+ EXPECT_FALSE(rhs.non_existing_attribute_value());
return _real->calc_with_limit(rhs, limit);
}
};
@@ -152,12 +155,12 @@ public:
~MyDistanceFunctionFactory() override;
std::unique_ptr<BoundDistanceFunction> for_query_vector(TypedCells lhs) override {
- EXPECT_TRUE(lhs.valid());
+ EXPECT_FALSE(lhs.non_existing_attribute_value());
return std::make_unique<MyBoundDistanceFunction>(_real->for_query_vector(lhs));
}
std::unique_ptr<BoundDistanceFunction> for_insertion_vector(TypedCells lhs) override {
- EXPECT_TRUE(lhs.valid());
+ EXPECT_FALSE(lhs.non_existing_attribute_value());
return std::make_unique<MyBoundDistanceFunction>(_real->for_insertion_vector(lhs));
}
};
diff --git a/searchlib/src/vespa/searchlib/tensor/distance_calculator.h b/searchlib/src/vespa/searchlib/tensor/distance_calculator.h
index 7ff9448c5af..1bdd3b39711 100644
--- a/searchlib/src/vespa/searchlib/tensor/distance_calculator.h
+++ b/searchlib/src/vespa/searchlib/tensor/distance_calculator.h
@@ -45,7 +45,7 @@ public:
if (has_single_subspace) {
auto cells = _attr_tensor.get_vector(docid, 0);
double min_rawscore = _dist_fun->min_rawscore();
- if ( ! cells.valid() ) [[unlikely]] {
+ if ( cells.non_existing_attribute_value() ) [[unlikely]] {
return min_rawscore;
}
return std::max(min_rawscore, _dist_fun->to_rawscore(_dist_fun->calc(cells)));
@@ -66,7 +66,7 @@ public:
double calc_with_limit(uint32_t docid, double limit) const noexcept {
if (has_single_subspace) {
auto cells = _attr_tensor.get_vector(docid, 0);
- if ( ! cells.valid() ) [[unlikely]] {
+ if ( cells.non_existing_attribute_value() ) [[unlikely]] {
return std::numeric_limits<double>::max();
}
return _dist_fun->calc_with_limit(cells, limit);
diff --git a/searchlib/src/vespa/searchlib/tensor/empty_subspace.cpp b/searchlib/src/vespa/searchlib/tensor/empty_subspace.cpp
index a7168b5eae6..131dcf05c60 100644
--- a/searchlib/src/vespa/searchlib/tensor/empty_subspace.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/empty_subspace.cpp
@@ -3,6 +3,8 @@
#include "empty_subspace.h"
#include "subspace_type.h"
+using vespalib::eval::TypedCells;
+
namespace search::tensor {
EmptySubspace::EmptySubspace(const SubspaceType& type)
@@ -11,7 +13,7 @@ EmptySubspace::EmptySubspace(const SubspaceType& type)
{
_empty_space.resize(type.mem_size());
// Set size to zero to signal empty/invalid subspace
- _cells = vespalib::eval::TypedCells(_empty_space.data(), type.cell_type(), 0);
+ _cells = TypedCells::create_non_existing_attribute_value(_empty_space.data(), type.cell_type(), type.size());
}
EmptySubspace::~EmptySubspace() = default;
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
index cdc3e81782a..1db688156e0 100644
--- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
+++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp
@@ -183,7 +183,7 @@ bool
HnswIndex<type>::have_closer_distance(HnswTraversalCandidate candidate, const HnswTraversalCandidateVector& result) const
{
auto candidate_vector = get_vector(candidate.nodeid);
- if (!candidate_vector.valid()) {
+ if (candidate_vector.non_existing_attribute_value()) {
/*
* We are in a read thread and the write thread has removed the
* tensor for the candidate. Return true to prevent the candidate
@@ -319,7 +319,7 @@ namespace {
double
calc_distance_helper(const BoundDistanceFunction &df, vespalib::eval::TypedCells rhs)
{
- if (!rhs.valid()) [[unlikely]] {
+ if (rhs.non_existing_attribute_value()) [[unlikely]] {
/*
* We are in a read thread and the write thread has removed the
* tensor.