Serialbox  2.2.0
Data serialization library and tools for C/C++, Python and Fortran
SavepointVector.cpp
Go to the documentation of this file.
1 //===-- serialbox/core/SavepointVector.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // S E R I A L B O X
4 //
5 // This file is distributed under terms of BSD license.
6 // See LICENSE.txt for more information
7 //
8 //===------------------------------------------------------------------------------------------===//
9 //
14 //===------------------------------------------------------------------------------------------===//
15 
17 #include "serialbox/core/Logging.h"
18 
19 namespace serialbox {
20 
21 int SavepointVector::insert(const SavepointImpl& savepoint) noexcept {
22  int idx = savepoints_.size();
23  if(index_.insert(typename index_type::value_type{savepoint, idx}).second) {
24  savepoints_.push_back(std::make_shared<SavepointImpl>(savepoint));
25  fields_.push_back(fields_per_savepoint_type());
26  return idx;
27  }
28  return -1;
29 }
30 
31 bool SavepointVector::addField(const SavepointImpl& savepoint, const FieldID& fieldID) noexcept {
32  int idx = find(savepoint);
33  if(idx != -1)
34  return addField(idx, fieldID);
35  return false;
36 }
37 
38 bool SavepointVector::addField(int idx, const FieldID& fieldID) noexcept {
39  return fields_[idx].insert({fieldID.name, fieldID.id}).second;
40 }
41 
42 bool SavepointVector::hasField(const SavepointImpl& savepoint, const std::string& field) noexcept {
43  int idx = find(savepoint);
44  if(idx != -1)
45  return hasField(idx, field);
46  return false;
47 }
48 
49 bool SavepointVector::hasField(int idx, const std::string& field) noexcept {
50  return (fields_[idx].find(field) != fields_[idx].end());
51 }
52 
53 FieldID SavepointVector::getFieldID(int idx, const std::string& field) const {
54  auto it = fields_[idx].find(field);
55  if(it != fields_[idx].end())
56  return FieldID{it->first, it->second};
57  throw Exception("field '%s' does not exists at savepoint '%s'", field, savepoints_[idx]->name());
58 }
59 
61  const std::string& field) const {
62  int idx = find(savepoint);
63  if(idx != -1)
64  return getFieldID(idx, field);
65  throw Exception("savepoint '%' does not exist", savepoint.toString());
66 }
67 
68 void SavepointVector::swap(SavepointVector& other) noexcept {
69  index_.swap(other.index_);
70  savepoints_.swap(other.savepoints_);
71  fields_.swap(other.fields_);
72 }
73 
74 bool SavepointVector::exists(const SavepointImpl& savepoint) const noexcept {
75  return (find(savepoint) != -1);
76 }
77 
78 int SavepointVector::find(const SavepointImpl& savepoint) const noexcept {
79  auto it = index_.find(savepoint);
80  return ((it != index_.end()) ? it->second : -1);
81 }
82 
84  noexcept {
85  return fields_[idx];
86 }
87 
89 SavepointVector::fieldsOf(const SavepointImpl& savepoint) const {
90  auto it = index_.find(savepoint);
91  if(it != index_.end())
92  return fieldsOf(it->second);
93  throw Exception("savepoint '%' does not exist", savepoint.toString());
94 }
95 
96 void SavepointVector::clear() noexcept {
97  savepoints_.clear();
98  index_.clear();
99  fields_.clear();
100 }
101 
102 json::json SavepointVector::toJSON() const {
103  json::json jsonNode;
104  assert(savepoints_.size() == fields_.size());
105 
106  for(std::size_t i = 0; i < savepoints_.size(); ++i)
107  jsonNode["savepoints"].push_back(savepoints_[i]->toJSON());
108 
109  for(std::size_t i = 0; i < fields_.size(); ++i) {
110  const std::string& savepoint = savepoints_[i]->name();
111  json::json fieldNode;
112 
113  if(fields_[i].empty())
114  fieldNode[savepoint] = nullptr;
115 
116  for(auto it = fields_[i].begin(), end = fields_[i].end(); it != end; ++it)
117  fieldNode[savepoint][it->first] = it->second;
118 
119  jsonNode["fields_per_savepoint"].push_back(fieldNode);
120  }
121 
122  return jsonNode;
123 }
124 
125 void SavepointVector::fromJSON(const json::json& jsonNode) {
126  index_.clear();
127  savepoints_.clear();
128  fields_.clear();
129 
130  if(jsonNode.is_null() || jsonNode.empty())
131  return;
132 
133  // Add savepoints
134  if(jsonNode.count("savepoints")) {
135  for(auto it = jsonNode["savepoints"].begin(), end = jsonNode["savepoints"].end(); it != end;
136  ++it) {
137  SavepointImpl sp(*it);
138  insert(sp);
139  }
140  }
141 
142  // Eeach savepoint needs an entry in the fields array (it can be null though)
143  if(jsonNode.count("fields_per_savepoint") &&
144  jsonNode["fields_per_savepoint"].size() != fields_.size())
145  throw Exception("inconsistent number of 'fields_per_savepoint' and 'savepoints'");
146 
147  for(std::size_t i = 0; i < fields_.size(); ++i) {
148  const json::json& fieldNode = jsonNode["fields_per_savepoint"][i][savepoints_[i]->name()];
149 
150  // Savepoint has no fields
151  if(fieldNode.is_null() || fieldNode.empty())
152  break;
153 
154  // Add fields
155  for(auto it = fieldNode.begin(), end = fieldNode.end(); it != end; ++it)
156  fields_[i].insert({it.key(), static_cast<unsigned int>(it.value())});
157  }
158 }
159 
160 std::ostream& operator<<(std::ostream& stream, const SavepointVector& s) {
161  stream << "SavepointVector = " << s.toJSON().dump(4);
162  return stream;
163 }
164 
165 } // namespace serialbox
void fromJSON(const json::json &jsonNode)
Construct from JSON node.
bool hasField(const SavepointImpl &savepoint, const std::string &field) noexcept
Check if savepoint has field field
FieldID getFieldID(const SavepointImpl &savepoint, const std::string &field) const
Get the FielID of field field at savepoint savepoint
bool empty() const noexcept
Returns a bool value indicating whether the savepoint vector is empty.
std::string toString() const
Convert savepoint to string.
int find(const SavepointImpl &savepoint) const noexcept
Find savepoint.
const fields_per_savepoint_type & fieldsOf(const SavepointImpl &savepoint) const
Access fields of savepoint.
Namespace of the serialbox library.
Definition: Archive.h:25
Uniquely identifiy a field.
Definition: FieldID.h:27
json::json toJSON() const
Convert to JSON.
std::unordered_map< std::string, unsigned int > fields_per_savepoint_type
Map of fields per savepoint.
void swap(SavepointVector &other) noexcept
Swap with other.
The SavepointVector manages the registered savepoints and their mapping to the stored fields...
int insert(const SavepointImpl &savepoint) noexcept
Insert savepoint in savepoint vector.
bool exists(const SavepointImpl &savepoint) const noexcept
Check if savepoint exists.
iterator end() noexcept
Returns an iterator pointing to the past-the-end savepoint in the vector.
bool addField(const SavepointImpl &savepoint, const FieldID &fieldID) noexcept
Add a field to the savepoint.
friend std::ostream & operator<<(std::ostream &stream, const SavepointVector &s)
Convert to stream.
Exception class which stores a human-readable error description.
Definition: Exception.h:30
iterator begin() noexcept
Returns an iterator pointing to the first savepoint in the vector.
Shared implementation of the Savepoint.
Definition: SavepointImpl.h:38
void clear() noexcept
All the elements Savepoints are dropped: their destructors are called, and they are removed from the ...