Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/search/hnsw_indexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,19 @@ StatusOr<double> ComputeSimilarity(const VectorItem& left, const VectorItem& rig
}

HnswIndex::HnswIndex(const SearchKey& search_key, HnswVectorFieldMetadata* vector, engine::Storage* storage,
std::random_device::result_type seed)
std::optional<std::random_device::result_type> seed)
: search_key(search_key),
metadata(vector),
storage(storage),
generator(std::mt19937(seed)),
seed(seed),
m_level_normalization_factor(1.0 / std::log(metadata->m)) {}

uint16_t HnswIndex::RandomizeLayer() {
if (!generator) {
generator = std::make_unique<std::mt19937>(seed.value_or(std::random_device()()));
}
Comment thread
advisedy marked this conversation as resolved.
Outdated
std::uniform_real_distribution<double> level_dist(0.0, 1.0);
double r = level_dist(generator);
double r = level_dist(*generator);
double log_val = -std::log(r);
double layer_val = log_val * m_level_normalization_factor;
return static_cast<uint16_t>(std::floor(layer_val));
Expand Down
7 changes: 5 additions & 2 deletions src/search/hnsw_indexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#pragma once

#include <memory>
#include <optional>
#include <random>
#include <string>
#include <vector>
Expand Down Expand Up @@ -89,11 +91,12 @@ struct HnswIndex {
HnswVectorFieldMetadata* metadata;
engine::Storage* storage = nullptr;

std::mt19937 generator;
std::optional<std::random_device::result_type> seed;
std::unique_ptr<std::mt19937> generator;
double m_level_normalization_factor;

HnswIndex(const SearchKey& search_key, HnswVectorFieldMetadata* vector, engine::Storage* storage,
std::random_device::result_type seed = std::random_device()());
std::optional<std::random_device::result_type> seed = std::nullopt);

static StatusOr<std::vector<VectorItem>> DecodeNodesToVectorItems(engine::Context& ctx,
const std::vector<NodeKey>& node_key,
Expand Down
6 changes: 6 additions & 0 deletions tests/cppunit/hnsw_index_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ TEST_F(HnswIndexTest, ComputeSimilarity) {
hnsw_index->metadata->distance_metric = redis::DistanceMetric::L2;
}

TEST_F(HnswIndexTest, RandomGeneratorIsInitializedLazily) {
EXPECT_FALSE(hnsw_index->generator);
hnsw_index->RandomizeLayer();
EXPECT_TRUE(hnsw_index->generator);
}

TEST_F(HnswIndexTest, RandomizeLayer) {
constexpr size_t kSampleSize = 50000;

Expand Down
Loading