This is an automated email from the ASF dual-hosted git repository.
Sober7135 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-graphar.git
The following commit(s) were added to refs/heads/main by this push:
new c7f31bc9 fix(cpp): preserve vertex IDs for nonzero builder starts
(#970)
c7f31bc9 is described below
commit c7f31bc9d3a47dc8ab75279ebaf78dc43673e80b
Author: Stefan Wang <[email protected]>
AuthorDate: Mon Sep 28 13:50:19 2026 -0700
fix(cpp): preserve vertex IDs for nonzero builder starts (#970)
* fix(c++): handle nonzero vertex start indices
Signed-off-by: 1fanwang <[email protected]>
* fix(c++): reject vertex indices below start
Signed-off-by: 1fanwang <[email protected]>
* fix(c++): enforce vertex storage invariants
Signed-off-by: 1fanwang <[email protected]>
* fix(c++): reject negative vertex start indices
Signed-off-by: 1fanwang <[email protected]>
* test(c++): prioritize vertex offset regression
Signed-off-by: 1fanwang <[email protected]>
* test(c++): check parquet read result
Signed-off-by: 1fanwang <[email protected]>
---------
Signed-off-by: 1fanwang <[email protected]>
---
cpp/src/graphar/high-level/vertices_builder.cc | 25 +++++----
cpp/src/graphar/high-level/vertices_builder.h | 17 +++----
cpp/test/test_builder.cc | 70 ++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 21 deletions(-)
diff --git a/cpp/src/graphar/high-level/vertices_builder.cc
b/cpp/src/graphar/high-level/vertices_builder.cc
index 00093831..cdd9280f 100644
--- a/cpp/src/graphar/high-level/vertices_builder.cc
+++ b/cpp/src/graphar/high-level/vertices_builder.cc
@@ -35,17 +35,9 @@ Status VerticesBuilder::validate(const Vertex& v, IdType
index,
if (validate_level == ValidateLevel::default_validate) {
validate_level = validate_level_;
}
- // no validate
- if (validate_level == ValidateLevel::no_validate) {
- return Status::OK();
- }
-
- // weak validate
- // can not add new vertices after dumping
- if (is_saved_) {
- return Status::Invalid(
- "The vertices builder has been saved, can not add "
- "new vertices any more");
+ if (start_vertex_index_ < 0) {
+ return Status::IndexError("The start vertex index ", start_vertex_index_,
+ " is smaller than 0");
}
// the start vertex index must be aligned with the chunk size
if (start_vertex_index_ % vertex_info_->GetChunkSize() != 0) {
@@ -59,7 +51,18 @@ Status VerticesBuilder::validate(const Vertex& v, IdType
index,
" is smaller than the start index ",
start_vertex_index_);
}
+ // no validate
+ if (validate_level == ValidateLevel::no_validate) {
+ return Status::OK();
+ }
+ // weak validate
+ // can not add new vertices after dumping
+ if (is_saved_) {
+ return Status::Invalid(
+ "The vertices builder has been saved, can not add "
+ "new vertices any more");
+ }
// strong validate
if (validate_level == ValidateLevel::strong_validate) {
for (auto& property : v.GetProperties()) {
diff --git a/cpp/src/graphar/high-level/vertices_builder.h
b/cpp/src/graphar/high-level/vertices_builder.h
index 4ddccada..6944d02f 100644
--- a/cpp/src/graphar/high-level/vertices_builder.h
+++ b/cpp/src/graphar/high-level/vertices_builder.h
@@ -338,17 +338,14 @@ class VerticesBuilder {
ValidateLevel validate_level = ValidateLevel::default_validate) {
// validate
GAR_RETURN_NOT_OK(validate(v, index, validate_level));
- // add a vertex
- if (index == -1) {
- v.SetId(vertices_.size());
- vertices_.push_back(v);
- } else {
- v.SetId(index);
- if (index >= static_cast<IdType>(vertices_.size())) {
- vertices_.resize(index + 1);
- }
- vertices_[index] = v;
+ const IdType local_index = index == -1
+ ? static_cast<IdType>(vertices_.size())
+ : index - start_vertex_index_;
+ v.SetId(start_vertex_index_ + local_index);
+ if (local_index >= static_cast<IdType>(vertices_.size())) {
+ vertices_.resize(local_index + 1);
}
+ vertices_[local_index] = v;
num_vertices_++;
return Status::OK();
}
diff --git a/cpp/test/test_builder.cc b/cpp/test/test_builder.cc
index 16ba5a21..ec686ca6 100644
--- a/cpp/test/test_builder.cc
+++ b/cpp/test/test_builder.cc
@@ -101,6 +101,76 @@ TEST_CASE_METHOD(GlobalFixture, "Test_vertices_builder") {
REQUIRE(indexed_vertex.GetId() == 7);
REQUIRE(indexed_vertex.Empty());
+ SECTION("nonzero start vertex index") {
+ const IdType nonzero_start_index = vertex_info->GetChunkSize();
+ auto nonzero_builder =
+ builder::VerticesBuilder::Make(vertex_info, "/tmp/nonzero/",
+ nonzero_start_index)
+ .value();
+ nonzero_builder->SetValidateLevel(ValidateLevel::weak_validate);
+
+ builder::Vertex auto_indexed_vertex;
+ auto_indexed_vertex.AddProperty("id", int64_t{10});
+ REQUIRE(nonzero_builder->AddVertex(auto_indexed_vertex).ok());
+ REQUIRE(auto_indexed_vertex.GetId() == nonzero_start_index);
+
+ builder::Vertex explicitly_indexed_vertex;
+ explicitly_indexed_vertex.AddProperty("id", int64_t{11});
+ REQUIRE(nonzero_builder
+ ->AddVertex(explicitly_indexed_vertex, nonzero_start_index + 1)
+ .ok());
+ REQUIRE(explicitly_indexed_vertex.GetId() == nonzero_start_index + 1);
+ REQUIRE(nonzero_builder->Dump().ok());
+
+ auto nonzero_chunk =
+ "/tmp/nonzero/vertex/person/id/chunk" +
+ std::to_string(nonzero_start_index / vertex_info->GetChunkSize());
+ std::unique_ptr<parquet::arrow::FileReader> nonzero_reader;
+ REQUIRE(graphar::util::OpenParquetArrowReader(
+ nonzero_chunk, arrow::default_memory_pool(), &nonzero_reader)
+ .ok());
+ auto maybe_nonzero_table = ReadParquetTable(nonzero_reader.get());
+ REQUIRE(maybe_nonzero_table.ok());
+ auto nonzero_table = maybe_nonzero_table.ValueOrDie();
+ REQUIRE(nonzero_table->num_rows() == 2);
+ auto vertex_index_array = std::static_pointer_cast<arrow::Int64Array>(
+ nonzero_table->GetColumnByName("_graphArVertexIndex")->chunk(0));
+ REQUIRE(vertex_index_array->Value(0) == nonzero_start_index);
+ REQUIRE(vertex_index_array->Value(1) == nonzero_start_index + 1);
+
+ auto no_validate_builder =
+ builder::VerticesBuilder::Make(vertex_info,
"/tmp/nonzero-no-validate/",
+ nonzero_start_index)
+ .value();
+ builder::Vertex below_start_vertex;
+ below_start_vertex.AddProperty("id", int64_t{9});
+ REQUIRE(
+ no_validate_builder->AddVertex(below_start_vertex, 5).IsIndexError());
+ REQUIRE_FALSE(below_start_vertex.HasId());
+ REQUIRE(no_validate_builder->GetNum() == 0);
+
+ auto unaligned_builder = builder::VerticesBuilder::Make(
+ vertex_info, "/tmp/unaligned-no-validate/",
+ nonzero_start_index + 50)
+ .value();
+ builder::Vertex unaligned_vertex;
+ unaligned_vertex.AddProperty("id", int64_t{10});
+ REQUIRE(unaligned_builder->AddVertex(unaligned_vertex).IsIndexError());
+ REQUIRE_FALSE(unaligned_vertex.HasId());
+ REQUIRE(unaligned_builder->GetNum() == 0);
+
+ auto negative_start_builder =
+ builder::VerticesBuilder::Make(
+ vertex_info, "/tmp/negative-no-validate/", -nonzero_start_index)
+ .value();
+ builder::Vertex negative_start_vertex;
+ negative_start_vertex.AddProperty("id", int64_t{10});
+ REQUIRE(negative_start_builder->AddVertex(negative_start_vertex)
+ .IsIndexError());
+ REQUIRE_FALSE(negative_start_vertex.HasId());
+ REQUIRE(negative_start_builder->GetNum() == 0);
+ }
+
// add vertices
std::ifstream fp(test_data_dir + "/ldbc_sample/person_0_0.csv");
std::string line;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]