diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-08-15 13:58:32 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-08-15 13:58:32 +0000 |
commit | 21337f626696182b68a8da2c1773784f5594027c (patch) | |
tree | 67e9bb97112a3d2bf3a59e60da68e0dc6f1ae292 /searchlib | |
parent | 6317934c7f314b7debf7df0a59d0e0228211b809 (diff) |
Add a time budget of 100ms. If counting not complete by then, abort, and let the count be incomplete.
Diffstat (limited to 'searchlib')
-rw-r--r-- | searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp | 22 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/tensor/hnsw_index.h | 2 |
2 files changed, 17 insertions, 7 deletions
diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp index a1515534cbc..f11381070e1 100644 --- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.cpp @@ -12,6 +12,7 @@ #include <vespa/vespalib/util/memory_allocator.h> #include <vespa/vespalib/util/rcuvector.hpp> #include <vespa/vespalib/util/size_literals.h> +#include <vespa/vespalib/util/time.h> #include <vespa/log/log.h> LOG_SETUP(".searchlib.tensor.hnsw_index"); @@ -30,6 +31,7 @@ constexpr float alloc_grow_factor = 0.3; // TODO: Adjust these numbers to what we accept as max in config. constexpr size_t max_level_array_size = 16; constexpr size_t max_link_array_size = 64; +constexpr vespalib::duration MAX_COUNT_DURATION(100ms); bool has_link_to(vespalib::ConstArrayRef<uint32_t> links, uint32_t id) { for (uint32_t link : links) { @@ -500,9 +502,13 @@ HnswIndex::get_state(const vespalib::slime::Inserter& inserter) const for (uint32_t hist_val : histograms.links_histogram) { links_hst_array.addLong(hist_val); } - uint32_t reachable = count_reachable_nodes(); - uint32_t unreachable = valid_nodes - reachable; - object.setLong("unreachable_nodes", unreachable); + auto count_result = count_reachable_nodes(); + uint32_t unreachable = valid_nodes - count_result.first; + if (count_result.second) { + object.setLong("unreachable_nodes", unreachable); + } else { + object.setLong("unreachable_nodes_incomplete_count", unreachable); + } auto entry_node = _graph.get_entry_node(); object.setLong("entry_docid", entry_node.docid); object.setLong("entry_level", entry_node.level); @@ -650,20 +656,24 @@ HnswIndex::check_link_symmetry() const return all_sym; } -uint32_t +std::pair<uint32_t, bool> HnswIndex::count_reachable_nodes() const { auto entry = _graph.get_entry_node(); int search_level = entry.level; if (search_level < 0) { - return 0; + return {0, true}; } std::vector<bool> visited(_graph.size()); LinkArray found_links; found_links.push_back(entry.docid); visited[entry.docid] = true; + vespalib::steady_time doom = vespalib::steady_clock::now() + MAX_COUNT_DURATION; while (search_level >= 0) { for (uint32_t idx = 0; idx < found_links.size(); ++idx) { + if (vespalib::steady_clock::now() > doom) { + return {found_links.size(), false}; + } uint32_t docid = found_links[idx]; auto neighbors = _graph.get_link_array(docid, search_level); for (uint32_t neighbor : neighbors) { @@ -674,7 +684,7 @@ HnswIndex::count_reachable_nodes() const } --search_level; } - return found_links.size(); + return {found_links.size(), true}; } } // namespace diff --git a/searchlib/src/vespa/searchlib/tensor/hnsw_index.h b/searchlib/src/vespa/searchlib/tensor/hnsw_index.h index 5bd9d17adc3..ef0f38c2263 100644 --- a/searchlib/src/vespa/searchlib/tensor/hnsw_index.h +++ b/searchlib/src/vespa/searchlib/tensor/hnsw_index.h @@ -183,7 +183,7 @@ public: HnswNode get_node(uint32_t docid) const; void set_node(uint32_t docid, const HnswNode &node); bool check_link_symmetry() const; - uint32_t count_reachable_nodes() const; + std::pair<uint32_t, bool> count_reachable_nodes() const; static vespalib::datastore::ArrayStoreConfig make_default_node_store_config(); static vespalib::datastore::ArrayStoreConfig make_default_link_store_config(); |