Program Listing for File MsgAccumulatorBundle.hpp¶
↰ Return to documentation for file (include/uitsl/distributed/MsgAccumulatorBundle.hpp)
#pragma once
#ifndef UITSL_DISTRIBUTED_MSGACCUMULATORBUNDLE_HPP_INCLUDE
#define UITSL_DISTRIBUTED_MSGACCUMULATORBUNDLE_HPP_INCLUDE
#include <algorithm>
#include <cassert>
#include <cstring>
#include <vector>
#include "../math/divide_utils.hpp"
namespace uitsl {
template<typename T>
class MsgAccumulatorBundle {
constexpr static size_t epoch_embed_items {
uitsl::div_ceil(sizeof(size_t), sizeof(T))
};
size_t data_size;
// holds data within size then epoch past the end
// within reserved capacity
std::vector<T> buff;
size_t const size() const { return buff.size(); }
public:
T* data() { return buff.data(); }
const T* data() const { return buff.data(); }
size_t byte_size() const {
return sizeof(T) * data_size + sizeof(size_t);
}
std::vector<T>& GetData() { return buff; }
const std::vector<T>& GetData() const { return buff; }
void Reset() {
buff.reserve(data_size + epoch_embed_items);
buff.resize(data_size);
std::fill(
std::begin(buff),
std::end(buff),
T{}
);
SetEpoch( size_t{} );
}
size_t GetEpoch() const {
assert( buff.size() == data_size );
size_t res;
std::memcpy(
&res,
buff.data() + data_size,
sizeof(size_t)
);
return res;
}
void SetEpoch(const size_t val) {
assert( buff.size() == data_size );
std::memcpy(
buff.data() + data_size,
&val,
sizeof(size_t)
);
}
void BumpEpoch(const size_t amt=1) {
SetEpoch( GetEpoch() + amt );
}
void BumpData(const std::vector<T>& bumps) {
assert( buff.size() == data_size );
assert( bumps.size() == data_size );
std::transform(
std::begin(bumps),
std::end(bumps),
std::begin(buff),
std::begin(buff),
std::plus<T>{}
);
}
explicit MsgAccumulatorBundle(const size_t data_size_)
: data_size( data_size_ )
{ Reset(); }
explicit MsgAccumulatorBundle(const std::vector<T>& data)
: data_size( data.size() )
, buff( data )
{
buff.reserve( data_size + epoch_embed_items);
SetEpoch( size_t{} );
}
explicit MsgAccumulatorBundle(std::vector<T>&& data)
: data_size( data.size() )
, buff( std::move(data) )
{
buff.reserve( data_size + epoch_embed_items);
SetEpoch( size_t{} );
}
MsgAccumulatorBundle(MsgAccumulatorBundle &&) = default;
MsgAccumulatorBundle& operator=(MsgAccumulatorBundle &&) = default;
MsgAccumulatorBundle& operator+=(const MsgAccumulatorBundle& rhs) {
BumpData( rhs.GetData() );
BumpEpoch( rhs.GetEpoch() );
return *this;
}
};
} // namespace uitsl
#endif // #ifndef UITSL_DISTRIBUTED_MSGACCUMULATORBUNDLE_HPP_INCLUDE