Apache GraphAr C++ Library
The C++ Library for Apache GraphAr
vertices_builder.h
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #pragma once
21 
22 #include <any>
23 #include <memory>
24 #include <string>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28 
29 #include "graphar/arrow/chunk_writer.h"
30 #include "graphar/graph_info.h"
31 #include "graphar/result.h"
32 
33 // forward declaration
34 namespace arrow {
35 class Array;
36 class Table;
37 } // namespace arrow
38 
39 namespace graphar::builder {
40 
45 class Vertex {
46  public:
47  Vertex() : empty_(true) {}
48 
54  explicit Vertex(IdType id) : id_(id), empty_(false) {}
55 
61  inline IdType GetId() const noexcept { return id_; }
62 
68  inline void SetId(IdType id) { id_ = id; }
69 
75  inline bool Empty() const noexcept { return empty_; }
76 
83  // TODO(@acezen): Enable the property to be a vector(list).
84  inline void AddProperty(const std::string& name, const std::any& val) {
85  empty_ = false;
86  properties_[name] = val;
87  }
88 
95  inline const std::any& GetProperty(const std::string& property) const {
96  return properties_.at(property);
97  }
98 
104  inline const std::unordered_map<std::string, std::any>& GetProperties()
105  const {
106  return properties_;
107  }
108 
115  inline bool ContainProperty(const std::string& property) {
116  return (properties_.find(property) != properties_.end());
117  }
118 
119  private:
120  IdType id_;
121  bool empty_;
122  std::unordered_map<std::string, std::any> properties_;
123 };
124 
131  public:
143  explicit VerticesBuilder(
144  const std::shared_ptr<VertexInfo>& vertex_info, const std::string& prefix,
145  IdType start_vertex_index = 0,
146  const ValidateLevel& validate_level = ValidateLevel::no_validate)
147  : vertex_info_(std::move(vertex_info)),
148  prefix_(prefix),
149  start_vertex_index_(start_vertex_index),
150  validate_level_(validate_level) {
151  if (validate_level_ == ValidateLevel::default_validate) {
152  throw std::runtime_error(
153  "default_validate is not allowed to be set as the global validate "
154  "level for VerticesBuilder");
155  }
156  vertices_.clear();
157  num_vertices_ = 0;
158  is_saved_ = false;
159  }
160 
164  inline void Clear() {
165  vertices_.clear();
166  num_vertices_ = 0;
167  is_saved_ = false;
168  }
169 
175  inline void SetValidateLevel(const ValidateLevel& validate_level) {
176  if (validate_level == ValidateLevel::default_validate) {
177  return;
178  }
179  validate_level_ = validate_level;
180  }
181 
187  inline ValidateLevel GetValidateLevel() const { return validate_level_; }
188 
212  Vertex& v, IdType index = -1, // NOLINT
213  ValidateLevel validate_level = ValidateLevel::default_validate) {
214  // validate
215  GAR_RETURN_NOT_OK(validate(v, index, validate_level));
216  // add a vertex
217  if (index == -1) {
218  v.SetId(vertices_.size());
219  vertices_.push_back(v);
220  } else {
221  v.SetId(index);
222  if (index >= static_cast<IdType>(vertices_.size()))
223  vertices_.resize(index + 1);
224  vertices_[index] = v;
225  }
226  num_vertices_++;
227  return Status::OK();
228  }
229 
235  IdType GetNum() const { return num_vertices_; }
236 
243  // construct the writer
244  VertexPropertyWriter writer(vertex_info_, prefix_, validate_level_);
245  IdType start_chunk_index =
246  start_vertex_index_ / vertex_info_->GetChunkSize();
247  // convert to table
248  GAR_ASSIGN_OR_RAISE(auto input_table, convertToTable());
249  // write table
250  GAR_RETURN_NOT_OK(writer.WriteTable(input_table, start_chunk_index));
251  GAR_RETURN_NOT_OK(
252  writer.WriteVerticesNum(num_vertices_ + start_vertex_index_));
253  is_saved_ = true;
254  vertices_.clear();
255  return Status::OK();
256  }
257 
267  static Result<std::shared_ptr<VerticesBuilder>> Make(
268  const std::shared_ptr<VertexInfo>& vertex_info, const std::string& prefix,
269  IdType start_vertex_index = 0,
270  const ValidateLevel& validate_level = ValidateLevel::no_validate) {
271  return std::make_shared<VerticesBuilder>(
272  vertex_info, prefix, start_vertex_index, validate_level);
273  }
274 
284  static Result<std::shared_ptr<VerticesBuilder>> Make(
285  const std::shared_ptr<GraphInfo>& graph_info, const std::string& label,
286  IdType start_vertex_index = 0,
287  const ValidateLevel& validate_level = ValidateLevel::no_validate) {
288  const auto vertex_info = graph_info->GetVertexInfo(label);
289  if (!vertex_info) {
290  return Status::KeyError("The vertex type ", label,
291  " doesn't exist in graph ", graph_info->GetName(),
292  ".");
293  }
294  return Make(vertex_info, graph_info->GetPrefix(), start_vertex_index,
295  validate_level);
296  }
297 
298  private:
307  Status validate(const Vertex& v, IdType index,
308  ValidateLevel validate_level) const;
309 
318  Status appendToArray(const std::shared_ptr<DataType>& type,
319  const std::string& property_name,
320  std::shared_ptr<arrow::Array>& array); // NOLINT
321 
330  template <Type type>
331  Status tryToAppend(const std::string& property_name,
332  std::shared_ptr<arrow::Array>& array); // NOLINT
333 
337  Result<std::shared_ptr<arrow::Table>> convertToTable();
338 
339  private:
340  std::shared_ptr<VertexInfo> vertex_info_;
341  std::string prefix_;
342  std::vector<Vertex> vertices_;
343  IdType start_vertex_index_;
344  IdType num_vertices_;
345  bool is_saved_;
346  ValidateLevel validate_level_;
347 };
348 
349 } // namespace graphar::builder
Status outcome object (success or error)
Definition: status.h:123
static Status KeyError(Args &&... args)
Definition: status.h:172
static Status OK()
Definition: status.h:157
The writer for vertex property group chunks.
Definition: chunk_writer.h:57
Status WriteVerticesNum(const IdType &count, ValidateLevel validate_level=ValidateLevel::default_validate) const
Write the number of vertices into the file.
Status WriteTable(const std::shared_ptr< arrow::Table > &input_table, const std::shared_ptr< PropertyGroup > &property_group, IdType start_chunk_index, ValidateLevel validate_level=ValidateLevel::default_validate) const
Write a single property group for multiple vertex chunks to corresponding files.
Vertex is designed for constructing vertices builder.
void SetId(IdType id)
Set id of the vertex.
const std::any & GetProperty(const std::string &property) const
Get a property of the vertex.
IdType GetId() const noexcept
Get id of the vertex.
void AddProperty(const std::string &name, const std::any &val)
Add a property to the vertex.
bool Empty() const noexcept
Check if the vertex is empty.
bool ContainProperty(const std::string &property)
Check if the vertex contains a property.
const std::unordered_map< std::string, std::any > & GetProperties() const
Get all properties of the vertex.
Vertex(IdType id)
Initialize the vertex with a given id.
VertexBuilder is designed for building and writing a collection of vertices.
void SetValidateLevel(const ValidateLevel &validate_level)
Set the validate level.
void Clear()
Clear the vertices in this VerciesBuilder.
static Result< std::shared_ptr< VerticesBuilder > > Make(const std::shared_ptr< GraphInfo > &graph_info, const std::string &label, IdType start_vertex_index=0, const ValidateLevel &validate_level=ValidateLevel::no_validate)
Construct a VertexBuilder from graph info and vertex label.
Status AddVertex(Vertex &v, IdType index=-1, ValidateLevel validate_level=ValidateLevel::default_validate)
Add a vertex with the given index.
VerticesBuilder(const std::shared_ptr< VertexInfo > &vertex_info, const std::string &prefix, IdType start_vertex_index=0, const ValidateLevel &validate_level=ValidateLevel::no_validate)
Initialize the VerticesBuilder.
static Result< std::shared_ptr< VerticesBuilder > > Make(const std::shared_ptr< VertexInfo > &vertex_info, const std::string &prefix, IdType start_vertex_index=0, const ValidateLevel &validate_level=ValidateLevel::no_validate)
Construct a VertexBuilder from vertex info.
IdType GetNum() const
Get the current number of vertices in the collection.
ValidateLevel GetValidateLevel() const
Get the validate level.
Status Dump()
Dump the collection into files.