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 26aa56aa27b7..515715eb6b1e 100644 --- a/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp +++ b/searchlib/src/tests/tensor/hnsw_index/hnsw_index_test.cpp @@ -103,7 +103,7 @@ class HnswIndexTest : public ::testing::Test { level_generator = generator.get(); index = std::make_unique(vectors, std::make_unique(vespalib::eval::CellType::FLOAT), std::move(generator), - HnswIndex::Config(5, 2, 10, 0, heuristic_select_neighbors)); + HnswIndexConfig(5, 2, 10, 0, heuristic_select_neighbors)); } void add_document(uint32_t docid, uint32_t max_level = 0) { level_generator->level = max_level; diff --git a/searchlib/src/tests/tensor/hnsw_index/stress_hnsw_mt.cpp b/searchlib/src/tests/tensor/hnsw_index/stress_hnsw_mt.cpp index 2a3f0b4af274..ccf19c7620dc 100644 --- a/searchlib/src/tests/tensor/hnsw_index/stress_hnsw_mt.cpp +++ b/searchlib/src/tests/tensor/hnsw_index/stress_hnsw_mt.cpp @@ -252,7 +252,7 @@ class Stressor : public ::testing::Test { uint32_t m = 16; index = std::make_unique(vectors, std::make_unique(), std::make_unique(m), - HnswIndex::Config(2*m, m, 200, 10, true)); + HnswIndexConfig(2*m, m, 200, 10, true)); } size_t get_rnd(size_t size) { return rng.nextUniform() * size; diff --git a/searchlib/src/vespa/searchlib/tensor/default_nearest_neighbor_index_factory.cpp b/searchlib/src/vespa/searchlib/tensor/default_nearest_neighbor_index_factory.cpp index 3bc736714636..b50c2e4ca700 100644 --- a/searchlib/src/vespa/searchlib/tensor/default_nearest_neighbor_index_factory.cpp +++ b/searchlib/src/vespa/searchlib/tensor/default_nearest_neighbor_index_factory.cpp @@ -33,11 +33,11 @@ DefaultNearestNeighborIndexFactory::make(const DocVectorAccess& vectors, { (void) vector_size; uint32_t m = params.max_links_per_node(); - HnswIndex::Config cfg(m * 2, - m, - params.neighbors_to_explore_at_insert(), - 10000, - true); + HnswIndexConfig cfg(m * 2, + m, + params.neighbors_to_explore_at_insert(), + 10000, + true); return std::make_unique(vectors, make_distance_function(params.distance_metric(), cell_type), make_random_level_generator(m), diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp index 5382d3695e10..fa7eab7a4cc5 100644 --- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp @@ -326,7 +326,7 @@ HnswIndex::search_layer(const TypedCells& input, uint32_t neighbors_to_find, } HnswIndex::HnswIndex(const DocVectorAccess& vectors, DistanceFunction::UP distance_func, - RandomLevelGenerator::UP level_generator, const Config& cfg) + RandomLevelGenerator::UP level_generator, const HnswIndexConfig& cfg) : _graph(), _vectors(vectors), _distance_func(std::move(distance_func)), diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.h b/searchlib/src/vespa/searchlib/tensor/hnsw_index.h index 231fd0b59e45..29fefcd0720c 100644 --- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.h +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.h @@ -2,6 +2,7 @@ #pragma once +#include "hnsw_index_config.h" #include "distance_function.h" #include "doc_vector_access.h" #include "hnsw_identity_mapping.h" @@ -36,33 +37,6 @@ namespace search::tensor { */ class HnswIndex : public NearestNeighborIndex { public: - class Config { - private: - uint32_t _max_links_at_level_0; - uint32_t _max_links_on_inserts; - uint32_t _neighbors_to_explore_at_construction; - uint32_t _min_size_before_two_phase; - bool _heuristic_select_neighbors; - - public: - Config(uint32_t max_links_at_level_0_in, - uint32_t max_links_on_inserts_in, - uint32_t neighbors_to_explore_at_construction_in, - uint32_t min_size_before_two_phase_in, - bool heuristic_select_neighbors_in) - : _max_links_at_level_0(max_links_at_level_0_in), - _max_links_on_inserts(max_links_on_inserts_in), - _neighbors_to_explore_at_construction(neighbors_to_explore_at_construction_in), - _min_size_before_two_phase(min_size_before_two_phase_in), - _heuristic_select_neighbors(heuristic_select_neighbors_in) - {} - uint32_t max_links_at_level_0() const { return _max_links_at_level_0; } - uint32_t max_links_on_inserts() const { return _max_links_on_inserts; } - uint32_t neighbors_to_explore_at_construction() const { return _neighbors_to_explore_at_construction; } - uint32_t min_size_before_two_phase() const { return _min_size_before_two_phase; } - bool heuristic_select_neighbors() const { return _heuristic_select_neighbors; } - }; - class HnswIndexCompactionSpec { CompactionSpec _level_arrays; CompactionSpec _link_arrays; @@ -109,7 +83,7 @@ class HnswIndex : public NearestNeighborIndex { DistanceFunction::UP _distance_func; RandomLevelGenerator::UP _level_generator; IdMapping _id_mapping; // mapping from docid to nodeid vector - Config _cfg; + HnswIndexConfig _cfg; HnswIndexCompactionSpec _compaction_spec; uint32_t max_links_for_level(uint32_t level) const; @@ -212,10 +186,10 @@ class HnswIndex : public NearestNeighborIndex { void internal_complete_add_node(uint32_t nodeid, uint32_t docid, uint32_t subspace, PreparedAddNode &prepared_node); public: HnswIndex(const DocVectorAccess& vectors, DistanceFunction::UP distance_func, - RandomLevelGenerator::UP level_generator, const Config& cfg); + RandomLevelGenerator::UP level_generator, const HnswIndexConfig& cfg); ~HnswIndex() override; - const Config& config() const { return _cfg; } + const HnswIndexConfig& config() const { return _cfg; } // Implements NearestNeighborIndex void add_document(uint32_t docid) override; diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index_config.h b/searchlib/src/vespa/searchlib/tensor/hnsw_index_config.h new file mode 100644 index 000000000000..c4022160f504 --- /dev/null +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index_config.h @@ -0,0 +1,39 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include + +namespace search::tensor { + +/* + * Class containing config for HnswIndex. + */ +class HnswIndexConfig { +private: + uint32_t _max_links_at_level_0; + uint32_t _max_links_on_inserts; + uint32_t _neighbors_to_explore_at_construction; + uint32_t _min_size_before_two_phase; + bool _heuristic_select_neighbors; + +public: + HnswIndexConfig(uint32_t max_links_at_level_0_in, + uint32_t max_links_on_inserts_in, + uint32_t neighbors_to_explore_at_construction_in, + uint32_t min_size_before_two_phase_in, + bool heuristic_select_neighbors_in) + : _max_links_at_level_0(max_links_at_level_0_in), + _max_links_on_inserts(max_links_on_inserts_in), + _neighbors_to_explore_at_construction(neighbors_to_explore_at_construction_in), + _min_size_before_two_phase(min_size_before_two_phase_in), + _heuristic_select_neighbors(heuristic_select_neighbors_in) + {} + uint32_t max_links_at_level_0() const { return _max_links_at_level_0; } + uint32_t max_links_on_inserts() const { return _max_links_on_inserts; } + uint32_t neighbors_to_explore_at_construction() const { return _neighbors_to_explore_at_construction; } + uint32_t min_size_before_two_phase() const { return _min_size_before_two_phase; } + bool heuristic_select_neighbors() const { return _heuristic_select_neighbors; } +}; + +}