diff --git a/src/data_cell/sparse_graph_datacell.cpp b/src/data_cell/sparse_graph_datacell.cpp index 3f7f64e7..0452e93a 100644 --- a/src/data_cell/sparse_graph_datacell.cpp +++ b/src/data_cell/sparse_graph_datacell.cpp @@ -42,6 +42,7 @@ SparseGraphDataCell::InsertNeighborsById(InnerIdType id, const Vectormax_capacity_ = std::max(this->max_capacity_, id + 1); if (not this->neighbors_.count(id)) { this->neighbors_.emplace(id, std::make_unique>(allocator_)); + this->total_count_ += 1; } this->neighbors_[id]->assign(neighbor_ids.begin(), neighbor_ids.begin() + size); } @@ -88,6 +89,7 @@ SparseGraphDataCell::Deserialize(StreamReader& reader) { this->neighbors_[key] = std::make_unique>(allocator_); StreamReader::ReadVector(reader, *(this->neighbors_[key])); } + this->total_count_ = size; } void SparseGraphDataCell::Resize(InnerIdType new_size){}; diff --git a/src/impl/odescent_graph_builder.cpp b/src/impl/odescent_graph_builder.cpp index e57c0597..63e24834 100644 --- a/src/impl/odescent_graph_builder.cpp +++ b/src/impl/odescent_graph_builder.cpp @@ -54,8 +54,11 @@ ODescent::Build(const uint32_t* valid_ids, int64_t data_num) { } else { data_num_ = flatten_interface_->TotalCount(); } - if (data_num_ <= 1) { - throw std::runtime_error("ODescent cannot build a graph with data_num less than 1"); + if (data_num_ <= 0) { + throw std::runtime_error("ODescent cannot build a graph with data_num less than 0"); + } else if (data_num_ == 1) { + graph.push_back(Linklist(allocator_)); + return true; } min_in_degree_ = std::min(min_in_degree_, data_num_ - 1); Vector(data_num_, allocator_).swap(points_lock_); @@ -379,11 +382,14 @@ ODescent::SaveGraph(GraphInterfacePtr& graph_storage) { id = valid_ids_[i]; } Vector edges(allocator_); - edges.resize(graph[i].neighbors.size()); - for (int j = 0; j < graph[i].neighbors.size(); ++j) { - edges[j] = graph[i].neighbors[j].id; - if (valid_ids_) { - edges[j] = valid_ids_[graph[i].neighbors[j].id]; + size_t size = graph[i].neighbors.size(); + if (size > 0) { + edges.resize(size); + for (int j = 0; j < size; ++j) { + edges[j] = graph[i].neighbors[j].id; + if (valid_ids_) { + edges[j] = valid_ids_[graph[i].neighbors[j].id]; + } } } graph_storage->InsertNeighborsById(id, edges); diff --git a/src/impl/odescent_graph_builder_test.cpp b/src/impl/odescent_graph_builder_test.cpp index 9b010ee4..0ca4d799 100644 --- a/src/impl/odescent_graph_builder_test.cpp +++ b/src/impl/odescent_graph_builder_test.cpp @@ -96,7 +96,7 @@ TEST_CASE("ODescent Build Test", "[ut][ODescent]") { valid_ids[i] = 2 * i; } } - if (num_vectors <= 1) { + if (num_vectors <= 0) { REQUIRE_THROWS(graph.Build(valid_ids.get(), num_vectors)); return; } @@ -107,9 +107,16 @@ TEST_CASE("ODescent Build Test", "[ut][ODescent]") { graph_interface = vsag::GraphInterface::MakeInstance(graph_param_ptr, param, partial_data); graph.SaveGraph(graph_interface); + auto id_map = [&](uint32_t id) -> uint32_t { return partial_data ? valid_ids[id] : id; }; + + if (num_vectors == 1) { + REQUIRE(graph_interface->TotalCount() == 1); + REQUIRE(graph_interface->GetNeighborSize(id_map(0)) == 0); + return; + } + float hit_edge_count = 0; int64_t indeed_max_degree = std::min(max_degree, (int64_t)num_vectors - 1); - auto id_map = [&](uint32_t id) -> uint32_t { return partial_data ? valid_ids[id] : id; }; for (int i = 0; i < num_vectors; ++i) { std::vector> ground_truths; uint32_t i_id = id_map(i);