Skip to content

Commit 16f0a56

Browse files
authored
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
1 parent d93c775 commit 16f0a56

3 files changed

Lines changed: 119 additions & 1 deletion

File tree

cpp/src/graphar/high-level/edges_builder.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <algorithm>
2323
#include <any>
24+
#include <map>
2425
#include <memory>
2526
#include <string>
2627
#include <unordered_map>
@@ -280,6 +281,30 @@ class EdgesBuilder {
280281
return Status::OK();
281282
}
282283

284+
/**
285+
* @brief Add a property to all edges in the collection.
286+
*
287+
* @param property name of the property
288+
* @param values vector of values where values[i] is mapped to the i-th edge
289+
* in chunk-major order with size equal to the edges collection
290+
*
291+
* @return Status: ok or Status::Invalid error.
292+
*/
293+
[[nodiscard]] Status AddPropertyColumn(const std::string& property,
294+
const std::vector<std::any>& values) {
295+
if (static_cast<IdType>(values.size()) != num_edges_) {
296+
return Status::Invalid(
297+
"The size of values vector is not equal to the number of edges.");
298+
}
299+
300+
IdType value = 0;
301+
for (auto& [id, edges] : edges_) {
302+
for (Edge& edge : edges) {
303+
edge.AddProperty(property, values[value++]);
304+
}
305+
}
306+
return Status::OK();
307+
}
283308
/**
284309
* @brief Get the current number of edges in the collection.
285310
*
@@ -471,7 +496,7 @@ class EdgesBuilder {
471496
std::shared_ptr<EdgeInfo> edge_info_;
472497
std::string prefix_;
473498
AdjListType adj_list_type_;
474-
std::unordered_map<IdType, std::vector<Edge>> edges_;
499+
std::map<IdType, std::vector<Edge>> edges_;
475500
IdType vertex_chunk_size_;
476501
IdType num_vertices_;
477502
IdType num_edges_;

cpp/src/graphar/high-level/vertices_builder.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,28 @@ class VerticesBuilder {
346346
return Status::OK();
347347
}
348348

349+
/**
350+
* @brief Add a property to all vertices in the collection.
351+
*
352+
* @param property name of the property
353+
* @param values vector of values where values[i] is mapped to the i-th vertex
354+
* in insertion order with size equal to the vertices collection
355+
*
356+
* @return Status: ok or Status::Invalid error.
357+
*/
358+
[[nodiscard]] Status AddPropertyColumn(const std::string& property,
359+
const std::vector<std::any>& values) {
360+
if (static_cast<IdType>(values.size()) != num_vertices_) {
361+
return Status::Invalid(
362+
"The size of values vector is not equal to the number of vertices.");
363+
}
364+
365+
for (size_t i = 0; i < vertices_.size(); i++) {
366+
vertices_[i].AddProperty(property, values[i]);
367+
}
368+
return Status::OK();
369+
}
370+
349371
/**
350372
* @brief Get the current number of vertices in the collection.
351373
*

cpp/test/test_builder.cc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,23 @@ TEST_CASE_METHOD(GlobalFixture, "Test_vertices_builder") {
119119
// check the number of vertices in builder
120120
REQUIRE(builder->GetNum() == lines);
121121

122+
// add property column
123+
std::vector<std::any> int_values(builder->GetNum());
124+
std::vector<std::any> string_values(builder->GetNum());
125+
for (IdType i = 0; i < builder->GetNum(); i++) {
126+
int_values[i] = i + 10;
127+
string_values[i] = std::to_string(i);
128+
}
129+
130+
REQUIRE(builder->AddPropertyColumn("id", int_values).ok());
131+
REQUIRE(builder->AddPropertyColumn("firstName", string_values).ok());
132+
133+
int_values.push_back(100);
134+
string_values.push_back("test");
135+
136+
REQUIRE(builder->AddPropertyColumn("id", int_values).IsInvalid());
137+
REQUIRE(builder->AddPropertyColumn("firstName", string_values).IsInvalid());
138+
122139
// dump to files
123140
REQUIRE(builder->Dump().ok());
124141

@@ -145,6 +162,37 @@ TEST_CASE_METHOD(GlobalFixture, "Test_vertices_builder") {
145162
auto row_group_meta = parquet_metadata->RowGroup(0);
146163
auto col_meta = row_group_meta->ColumnChunk(0);
147164
REQUIRE(col_meta->compression() == parquet::Compression::LZ4);
165+
166+
// check that properties were added correctly
167+
auto name_file = "/tmp/vertex/person/firstName_lastName_gender/chunk0";
168+
169+
std::unique_ptr<parquet::arrow::FileReader> name_reader;
170+
171+
REQUIRE(graphar::util::OpenParquetArrowReader(
172+
name_file, arrow::default_memory_pool(), &name_reader)
173+
.ok());
174+
175+
auto id_col = parquet_table->GetColumnByName("id");
176+
177+
auto maybe_name_table = name_reader->ReadTable();
178+
REQUIRE(maybe_name_table.ok());
179+
auto name_table = maybe_name_table.ValueOrDie();
180+
auto name_col = name_table->GetColumnByName("firstName");
181+
182+
REQUIRE(name_col != nullptr);
183+
REQUIRE(id_col != nullptr);
184+
185+
REQUIRE(id_col->type()->id() == arrow::Type::INT64);
186+
auto id_array = std::static_pointer_cast<arrow::Int64Array>(id_col->chunk(0));
187+
auto name_array =
188+
std::static_pointer_cast<arrow::StringArray>(name_col->chunk(0));
189+
190+
for (IdType i = 0; i < id_array->length(); i++) {
191+
REQUIRE(id_array->Value(i) == i + 10);
192+
}
193+
for (IdType i = 0; i < name_array->length(); i++) {
194+
REQUIRE(name_array->GetString(i) == std::to_string(i));
195+
}
148196
}
149197

150198
TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
@@ -221,6 +269,17 @@ TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
221269
// check the number of edges in builder
222270
REQUIRE(builder->GetNum() == lines);
223271

272+
// add property column
273+
std::vector<std::any> string_values(builder->GetNum(),
274+
std::string("test_edge"));
275+
276+
REQUIRE(builder->AddPropertyColumn("creationDate", string_values).ok());
277+
278+
string_values.push_back(std::string("test"));
279+
280+
REQUIRE(
281+
builder->AddPropertyColumn("creationDate", string_values).IsInvalid());
282+
224283
// dump to files
225284
REQUIRE(builder->Dump().ok());
226285

@@ -251,5 +310,17 @@ TEST_CASE_METHOD(GlobalFixture, "test_edges_builder") {
251310
auto row_group_meta = parquet_metadata->RowGroup(0);
252311
auto col_meta = row_group_meta->ColumnChunk(0);
253312
REQUIRE(col_meta->compression() == parquet::Compression::LZ4);
313+
// check that properties were added correctly
314+
315+
auto date_col = parquet_table->GetColumnByName("creationDate");
316+
317+
REQUIRE(date_col != nullptr);
318+
319+
auto string_array =
320+
std::static_pointer_cast<arrow::StringArray>(date_col->chunk(0));
321+
322+
for (IdType i = 0; i < string_array->length(); i++) {
323+
REQUIRE(string_array->GetString(i) == "test_edge");
324+
}
254325
}
255326
} // namespace graphar

0 commit comments

Comments
 (0)