This is an automated email from the ASF dual-hosted git repository.
SYaoJun 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 16f0a56c feat(cpp): Support to write vector in
VerticesBuilder/EdgeBuilder (#930)
16f0a56c is described below
commit 16f0a56c3bb88885c2914b1adda99a5986eaf7b3
Author: amrSherif12 <[email protected]>
AuthorDate: Tue Jun 2 02:11:16 2026 +0300
feat(cpp): Support to write vector in VerticesBuilder/EdgeBuilder (#930)
* feat(cpp): Support to write vector in VerticesBuilder/EdgeBuilder
* feat(cpp): fixing final changes and typos
* feat(cpp): added missing library
---
cpp/src/graphar/high-level/edges_builder.h | 27 +++++++++-
cpp/src/graphar/high-level/vertices_builder.h | 22 +++++++++
cpp/test/test_builder.cc | 71 +++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/cpp/src/graphar/high-level/edges_builder.h
b/cpp/src/graphar/high-level/edges_builder.h
index ce847f4e..382d0b96 100644
--- a/cpp/src/graphar/high-level/edges_builder.h
+++ b/cpp/src/graphar/high-level/edges_builder.h
@@ -21,6 +21,7 @@
#include <algorithm>
#include <any>
+#include <map>
#include <memory>
#include <string>
#include <unordered_map>
@@ -280,6 +281,30 @@ class EdgesBuilder {
return Status::OK();
}
+ /**
+ * @brief Add a property to all edges in the collection.
+ *
+ * @param property name of the property
+ * @param values vector of values where values[i] is mapped to the i-th edge
+ * in chunk-major order with size equal to the edges collection
+ *
+ * @return Status: ok or Status::Invalid error.
+ */
+ [[nodiscard]] Status AddPropertyColumn(const std::string& property,
+ const std::vector<std::any>& values) {
+ if (static_cast<IdType>(values.size()) != num_edges_) {
+ return Status::Invalid(
+ "The size of values vector is not equal to the number of edges.");
+ }
+
+ IdType value = 0;
+ for (auto& [id, edges] : edges_) {
+ for (Edge& edge : edges) {
+ edge.AddProperty(property, values[value++]);
+ }
+ }
+ return Status::OK();
+ }
/**
* @brief Get the current number of edges in the collection.
*
@@ -471,7 +496,7 @@ class EdgesBuilder {
std::shared_ptr<EdgeInfo> edge_info_;
std::string prefix_;
AdjListType adj_list_type_;
- std::unordered_map<IdType, std::vector<Edge>> edges_;
+ std::map<IdType, std::vector<Edge>> edges_;
IdType vertex_chunk_size_;
IdType num_vertices_;
IdType num_edges_;
diff --git a/cpp/src/graphar/high-level/vertices_builder.h
b/cpp/src/graphar/high-level/vertices_builder.h
index 38632a22..019df6f0 100644
--- a/cpp/src/graphar/high-level/vertices_builder.h
+++ b/cpp/src/graphar/high-level/vertices_builder.h
@@ -346,6 +346,28 @@ class VerticesBuilder {
return Status::OK();
}
+ /**
+ * @brief Add a property to all vertices in the collection.
+ *
+ * @param property name of the property
+ * @param values vector of values where values[i] is mapped to the i-th
vertex
+ * in insertion order with size equal to the vertices collection
+ *
+ * @return Status: ok or Status::Invalid error.
+ */
+ [[nodiscard]] Status AddPropertyColumn(const std::string& property,
+ const std::vector<std::any>& values) {
+ if (static_cast<IdType>(values.size()) != num_vertices_) {
+ return Status::Invalid(
+ "The size of values vector is not equal to the number of vertices.");
+ }
+
+ for (size_t i = 0; i < vertices_.size(); i++) {
+ vertices_[i].AddProperty(property, values[i]);
+ }
+ return Status::OK();
+ }
+
/**
* @brief Get the current number of vertices in the collection.
*
diff --git a/cpp/test/test_builder.cc b/cpp/test/test_builder.cc
index 9a25b5af..67026e26 100644
--- a/cpp/test/test_builder.cc
+++ b/cpp/test/test_builder.cc
@@ -119,6 +119,23 @@ TEST_CASE_METHOD(GlobalFixture, "Test_vertices_builder") {
// check the number of vertices in builder
REQUIRE(builder->GetNum() == lines);
+ // add property column
+ std::vector<std::any> int_values(builder->GetNum());
+ std::vector<std::any> string_values(builder->GetNum());
+ for (IdType i = 0; i < builder->GetNum(); i++) {
+ int_values[i] = i + 10;
+ string_values[i] = std::to_string(i);
+ }
+
+ REQUIRE(builder->AddPropertyColumn("id", int_values).ok());
+ REQUIRE(builder->AddPropertyColumn("firstName", string_values).ok());
+
+ int_values.push_back(100);
+ string_values.push_back("test");
+
+ REQUIRE(builder->AddPropertyColumn("id", int_values).IsInvalid());
+ REQUIRE(builder->AddPropertyColumn("firstName", string_values).IsInvalid());
+
// dump to files
REQUIRE(builder->Dump().ok());
@@ -145,6 +162,37 @@ TEST_CASE_METHOD(GlobalFixture, "Test_vertices_builder") {
auto row_group_meta = parquet_metadata->RowGroup(0);
auto col_meta = row_group_meta->ColumnChunk(0);
REQUIRE(col_meta->compression() == parquet::Compression::LZ4);
+
+ // check that properties were added correctly
+ auto name_file = "/tmp/vertex/person/firstName_lastName_gender/chunk0";
+
+ std::unique_ptr<parquet::arrow::FileReader> name_reader;
+
+ REQUIRE(graphar::util::OpenParquetArrowReader(
+ name_file, arrow::default_memory_pool(), &name_reader)
+ .ok());
+
+ auto id_col = parquet_table->GetColumnByName("id");
+
+ auto maybe_name_table = name_reader->ReadTable();
+ REQUIRE(maybe_name_table.ok());
+ auto name_table = maybe_name_table.ValueOrDie();
+ auto name_col = name_table->GetColumnByName("firstName");
+
+ REQUIRE(name_col != nullptr);
+ REQUIRE(id_col != nullptr);
+
+ REQUIRE(id_col->type()->id() == arrow::Type::INT64);
+ auto id_array =
std::static_pointer_cast<arrow::Int64Array>(id_col->chunk(0));
+ auto name_array =
+ std::static_pointer_cast<arrow::StringArray>(name_col->chunk(0));
+
+ for (IdType i = 0; i < id_array->length(); i++) {
+ REQUIRE(id_array->Value(i) == i + 10);
+ }
+ for (IdType i = 0; i < name_array->length(); i++) {
+ REQUIRE(name_array->GetString(i) == std::to_string(i));
+ }
}
TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
@@ -221,6 +269,17 @@ TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
// check the number of edges in builder
REQUIRE(builder->GetNum() == lines);
+ // add property column
+ std::vector<std::any> string_values(builder->GetNum(),
+ std::string("test_edge"));
+
+ REQUIRE(builder->AddPropertyColumn("creationDate", string_values).ok());
+
+ string_values.push_back(std::string("test"));
+
+ REQUIRE(
+ builder->AddPropertyColumn("creationDate", string_values).IsInvalid());
+
// dump to files
REQUIRE(builder->Dump().ok());
@@ -251,5 +310,17 @@ TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
auto row_group_meta = parquet_metadata->RowGroup(0);
auto col_meta = row_group_meta->ColumnChunk(0);
REQUIRE(col_meta->compression() == parquet::Compression::LZ4);
+ // check that properties were added correctly
+
+ auto date_col = parquet_table->GetColumnByName("creationDate");
+
+ REQUIRE(date_col != nullptr);
+
+ auto string_array =
+ std::static_pointer_cast<arrow::StringArray>(date_col->chunk(0));
+
+ for (IdType i = 0; i < string_array->length(); i++) {
+ REQUIRE(string_array->GetString(i) == "test_edge");
+ }
}
} // namespace graphar
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]