6#if defined(WMTK_ENABLED_DEV_MODE)
8#include <spdlog/spdlog.h>
11#define WMTK_CACHING_ATTRIBUTE_INLINE
15#define WMTK_CACHING_ATTRIBUTE_INLINE inline
19#if defined(WMTK_ENABLED_DEV_MODE)
21void CachingAttribute<T>::print_state(std::string_view prefix)
const
23 if constexpr (std::is_same_v<T, Rational>) {
24 }
else if constexpr (std::is_same_v<T, char>) {
25 auto toint = [](
auto&& v)
noexcept -> int64_t {
return v; };
27 "Attribute {}: [{}] on transaction {} of {}",
30 m_current_transaction_index,
31 m_transaction_starts.size());
32 spdlog::info(
"Data: {}", fmt::join(std::views::transform(BaseType::m_data, toint),
","));
33 for (
size_t j = 0; j < m_transaction_starts.size(); ++j) {
34 size_t start = m_transaction_starts[j];
36 if (j == m_transaction_starts.size() - 1) {
39 end = m_transaction_starts[j + 1];
41 spdlog::info(
"Detailing transaction {} with value indices {}->{}", j, start, end);
43 for (
size_t k = start; k < end; ++k) {
44 const auto& [attr_index, table_index] = m_indices[k];
46 "attr index {} has table index {} and value {}",
50 std::views::transform(
51 std::span(m_buffer.data() + table_index, BaseType::dimension()),
63 -> std::vector<std::pair<size_t, size_t>>::const_iterator
65 return m_indices.begin() + m_transaction_starts[scope_index];
69 ->
std::vector<
std::pair<
size_t,
size_t>>::const_iterator
72 return m_indices.begin() + m_indices_end;
77 -> std::vector<std::pair<size_t, size_t>>::const_reverse_iterator
79 return std::reverse_iterator(transaction_start_begin(scope_index));
83 ->
std::vector<
std::pair<
size_t,
size_t>>::const_reverse_iterator
85 return std::reverse_iterator(final_transaction_end());
92 assert(has_transactions());
93 assert(at_current_scope());
102 assert(at_current_scope());
104 auto data = BaseType::template vector_attribute<D>(index);
105 assert(data.cols() == 1);
106 if constexpr (D != Eigen::Dynamic) {
107 assert(data.size() == D);
110 if (has_transactions()) {
122 if (!at_current_scope()) {
123 assert(m_current_transaction_index < m_transaction_starts.size());
125 const T* ptr = get_value(index);
126 if (ptr !=
nullptr) {
127 const int dim = BaseType::dimension();
132 return BaseType::template const_vector_attribute<D>(index);
138 assert(at_current_scope());
139 T& value = BaseType::scalar_attribute(index);
140 if (has_transactions()) {
150 if (!at_current_scope()) {
151 assert(m_current_transaction_index < m_transaction_starts.size());
153 const T* ptr = get_value(index);
154 if (ptr !=
nullptr) {
159 return BaseType::const_scalar_attribute(index);
165 int8_t vector_index)
const ->
const T&
167 if (!at_current_scope()) {
168 assert(m_current_transaction_index < m_transaction_starts.size());
170 const T* ptr = get_value(index);
171 if (ptr !=
nullptr) {
172 const int dim = BaseType::dimension();
173 assert(vector_index < dim);
174 return ptr[vector_index];
177 return BaseType::const_vector_single_value(index, vector_index);
191 pop(preserve_changes);
197 m_transaction_starts.clear();
198 change_to_current_scope();
206 if (!has_transactions()) {
210 m_indices_end = m_transaction_starts.back();
211 m_buffer_end = m_indices[m_indices_end].second;
220 if (m_indices_end + 1 >= m_indices.size()) {
221 assert(m_indices.size() > 2);
222 m_indices.resize(m_indices.size() * 1.75);
225 if (m_buffer_end + data_size >= m_buffer.size()) {
226 assert(m_buffer.size() > 2);
227 m_buffer.resize(m_buffer.size() * 1.75);
232template <
typename Derived>
235 const Eigen::MatrixBase<Derived>& value)
239 size_t dim = value.size();
242 update_buffer_sizes_for_add(dim);
247 m_indices[m_indices_end] = {index, m_buffer_end};
250 assert(m_buffer.size() >= m_buffer_end + dim);
252 std::copy(value.begin(), value.end(), m_buffer.begin() + m_buffer_end);
255 assert(m_buffer_end == m_indices_end * dim);
261 update_buffer_sizes_for_add(1);
263 m_indices[m_indices_end] = {index, m_buffer_end};
264 m_buffer[m_buffer_end] = value;
268 assert(m_buffer_end == m_indices_end);
275 apply_cache(BaseType::m_data);
281 assert(at_current_scope());
282 for (
auto it = final_transaction_rbegin();
283 it != transaction_start_rend(current_transaction_index() - 1);
285 const auto& [global, local] = *it;
286 auto a = BaseType::vector_attribute(global, other);
287 auto b = BaseType::const_vector_attribute_without_stride(local, m_buffer);
295 for (
auto it = transaction_start_begin(current_transaction_index());
296 it != final_transaction_end();
298 const auto& [global_index, local_index] = *it;
299 if (global_index == index) {
300 const T* ptr = m_buffer.data() + local_index;
310 assert(at_current_scope());
312 m_transaction_starts.emplace_back(m_indices_end);
313 change_to_current_scope();
318 assert(at_current_scope());
320 if (!preserve_changes) {
325 m_transaction_starts.pop_back();
327 change_to_current_scope();
328 if (!has_transactions()) {
338 assert(at_current_scope());
339 assert(has_transactions());
347 assert(!at_current_scope());
348 m_current_transaction_index++;
355 if (at_current_scope()) {
356 assert(has_transactions());
358 m_current_transaction_index--;
363 m_current_transaction_index = transaction_depth();
368 assert(m_current_transaction_index <= m_transaction_starts.size());
369 return m_current_transaction_index == transaction_depth();
375 return m_transaction_starts.size();
381 return !m_transaction_starts.empty();
385#undef WMTK_CACHING_ATTRIBUTE_INLINE
#define WMTK_CACHING_ATTRIBUTE_INLINE
ConstMapResult< D > const_vector_attribute(int64_t index) const
default immutable vector access
const T & const_scalar_attribute(int64_t index) const
default immutable scalar access
void rollback_current_scope()
std::vector< std::pair< size_t, size_t > >::const_iterator final_transaction_end() const
void pop(bool preserve_changes)
MapResult< D > vector_attribute(int64_t index)
default mutable vector access
bool at_current_scope() const
checks that we are viewing the active state of the attribute
const T * get_value(int64_t index) const
void change_to_current_scope()
typename BaseType::template MapResult< D > MapResult
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator transaction_start_rend(size_t scope_index) const
void change_to_previous_scope()
int64_t transaction_depth() const
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator final_transaction_rbegin() const
void pop_scope(bool preserve_changes)
void cache(int64_t index, const Eigen::MatrixBase< Derived > &value)
void change_to_next_scope()
std::vector< std::pair< size_t, size_t > >::const_iterator transaction_start_begin(size_t scope_index) const
bool has_transactions() const
typename BaseType::template ConstMapResult< D > ConstMapResult
T & scalar_attribute(int64_t index)
default mutable scalar access
const T & const_vector_single_value(int64_t index, int8_t vector_index) const
specialized immutable scalar access useful for topological operations
void update_buffer_sizes_for_add(size_t data_size)