spla
Loading...
Searching...
No Matches
storage_manager.hpp
Go to the documentation of this file.
1/**********************************************************************************/
2/* This file is part of spla project */
3/* https://github.com/SparseLinearAlgebra/spla */
4/**********************************************************************************/
5/* MIT License */
6/* */
7/* Copyright (c) 2023 SparseLinearAlgebra */
8/* */
9/* Permission is hereby granted, free of charge, to any person obtaining a copy */
10/* of this software and associated documentation files (the "Software"), to deal */
11/* in the Software without restriction, including without limitation the rights */
12/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13/* copies of the Software, and to permit persons to whom the Software is */
14/* furnished to do so, subject to the following conditions: */
15/* */
16/* The above copyright notice and this permission notice shall be included in all */
17/* copies or substantial portions of the Software. */
18/* */
19/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25/* SOFTWARE. */
26/**********************************************************************************/
27
28#ifndef SPLA_STORAGE_MANAGER_HPP
29#define SPLA_STORAGE_MANAGER_HPP
30
31#include <spla/config.hpp>
32
33#include <core/tdecoration.hpp>
34
35#include <algorithm>
36#include <functional>
37#include <queue>
38#include <utility>
39#include <vector>
40
41namespace spla {
42
56 template<typename T, typename F, int capacity>
57 class StorageManager final {
58 public:
60 typedef std::function<void(Storage& storage)> Function;
61
62 explicit StorageManager();
63
64 void register_constructor(F format, Function function);
65 void register_validator(F format, Function function);
66 void register_discard(F format, Function function);
67 void register_validator_discard(F format, Function function);
68 void register_converter(F from, F to, Function function);
69
70 void validate_ctor(F format, Storage& storage);
71 void validate_rw(F format, Storage& storage);
72 void validate_rwd(F format, Storage& storage);
73 void validate_wd(F format, Storage& storage);
74
75 private:
76 std::vector<std::vector<std::pair<int, int>>> m_convert_rules;
77 std::vector<Function> m_constructors;
78 std::vector<Function> m_validators;
79 std::vector<Function> m_discards;
80 std::vector<Function> m_converters;
81 };
82
83 template<typename T, typename F, int capacity>
85 m_convert_rules.resize(capacity);
86 m_constructors.resize(capacity);
87 m_validators.resize(capacity);
88 m_discards.resize(capacity);
89 }
90
91 template<typename T, typename F, int capacity>
93 const int i = static_cast<int>(format);
94 m_constructors[i] = std::move(function);
95 }
96 template<typename T, typename F, int capacity>
98 const int i = static_cast<int>(format);
99 m_validators[i] = std::move(function);
100 }
101 template<typename T, typename F, int capacity>
103 const int i = static_cast<int>(format);
104 m_discards[i] = std::move(function);
105 }
106 template<typename T, typename F, int capacity>
108 const int i = static_cast<int>(format);
109 m_discards[i] = m_validators[i] = std::move(function);
110 }
111 template<typename T, typename F, int capacity>
113 const int i = static_cast<int>(from);
114 const int j = static_cast<int>(to);
115 const int id = static_cast<int>(m_converters.size());
116 m_convert_rules[i].push_back({j, id});
117 m_converters.push_back(std::move(function));
118 }
119
120 template<typename T, typename F, int capacity>
122 const int i = static_cast<int>(format);
123 if (!storage.get_ptr_i(i)) {
124 m_constructors[i](storage);
125 }
126 }
127 template<typename T, typename F, int capacity>
129 if (storage.is_valid(format)) {
130 return;
131 }
132 if (!storage.is_valid_any()) {
133 const int i = static_cast<int>(format);
134 if (!storage.get_ptr_i(i)) {
135 if (!m_constructors[i]) {
136 LOG_MSG(Status::NotImplemented, "no such constructor for format " << i);
137 assert(false);
138 return;
139 }
140 m_constructors[i](storage);
141 }
142 if (m_validators[i]) {
143 m_validators[i](storage);
144 }
145 storage.validate(format);
146 return;
147 }
148
149 const int source = -1;
150 const int infinity = -2;
151 const int target = static_cast<int>(format);
152
153 std::array<int, capacity> reached;
154 std::queue<int> queue;
155 reached.fill(infinity);
156
157 assert(storage.is_valid_any());
158
159 for (int i = 0; i < capacity; ++i) {
160 if (storage.is_valid_i(i)) {
161 reached[i] = source;
162 queue.push(i);
163 }
164 }
165
166 while (reached[target] == infinity) {
167 if (queue.empty()) {
168 LOG_MSG(Status::NotImplemented, "no conversion path to target format " << target);
169 assert(false);
170 return;
171 }
172
173 int u = queue.front();
174 queue.pop();
175
176 for (const auto& target_format : m_convert_rules[u]) {
177 if (reached[target_format.first] == infinity) {
178 reached[target_format.first] = u;
179 queue.push(target_format.first);
180 }
181 }
182 }
183
184 std::vector<std::pair<int, int>> path;
185 int current = target;
186
187 while (reached[current] != source) {
188 path.push_back({reached[current], current});
189 current = reached[current];
190 }
191
192 for (auto iter = path.rbegin(); iter != path.rend(); ++iter) {
193 std::pair<int, int> from_to = *iter;
194 auto search_predicate = [from_to](const std::pair<int, int>& rule) { return rule.first == from_to.second; };
195 auto rule = std::find_if(m_convert_rules[from_to.first].begin(), m_convert_rules[from_to.first].end(), search_predicate);
196
197 if (storage.get_ref_i(from_to.second).is_null()) {
198 m_constructors[from_to.second](storage);
199 }
200
201 m_converters[rule->second](storage);
202 storage.validate(static_cast<F>(from_to.second));
203 }
204 }
205 template<typename T, typename F, int capacity>
207 validate_rw(format, storage);
208 storage.invalidate();
209 storage.validate(format);
210 }
211 template<typename T, typename F, int capacity>
213 const int i = static_cast<int>(format);
214 if (!storage.get_ptr_i(i)) {
215 m_constructors[i](storage);
216 }
217 if (m_discards[i]) {
218 m_discards[i](storage);
219 }
220 storage.invalidate();
221 storage.validate(format);
222 }
223
228}// namespace spla
229
230#endif//SPLA_STORAGE_MANAGER_HPP
General format converter for vector or matrix decoration storage.
Definition storage_manager.hpp:57
TDecorationStorage< T, F, capacity > Storage
Definition storage_manager.hpp:59
std::function< void(Storage &storage)> Function
Definition storage_manager.hpp:60
Storage for decorators with data of a particular vector or matrix object.
Definition tdecoration.hpp:70
ref_ptr< TDecoration< T > > & get_ref_i(int index)
Definition tdecoration.hpp:72
void invalidate()
Definition tdecoration.hpp:84
void validate(F format)
Definition tdecoration.hpp:83
bool is_valid(F format) const
Definition tdecoration.hpp:82
TDecoration< T > * get_ptr_i(int index)
Definition tdecoration.hpp:73
bool is_valid_any() const
Definition tdecoration.hpp:80
bool is_valid_i(int index) const
Definition tdecoration.hpp:81
void register_converter(F from, F to, Function function)
Definition storage_manager.hpp:112
StorageManager()
Definition storage_manager.hpp:84
void register_discard(F format, Function function)
Definition storage_manager.hpp:102
void validate_wd(F format, Storage &storage)
Definition storage_manager.hpp:212
void validate_rw(F format, Storage &storage)
Definition storage_manager.hpp:128
void validate_ctor(F format, Storage &storage)
Definition storage_manager.hpp:121
void validate_rwd(F format, Storage &storage)
Definition storage_manager.hpp:206
void register_validator(F format, Function function)
Definition storage_manager.hpp:97
void register_validator_discard(F format, Function function)
Definition storage_manager.hpp:107
void register_constructor(F format, Function function)
Definition storage_manager.hpp:92
#define LOG_MSG(status, msg)
Definition logger.hpp:66
Definition algorithm.hpp:37