25#include "bitpit_common.hpp"
27#include "piercedSync.hpp"
42 : type(_type), data(nullptr)
52 std::unique_ptr<std::vector<std::size_t>> new_data;
54 new_data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(*(other.data)));
60 for (std::size_t k = 0; k < INFO_COUNT; ++k) {
61 info[k] = other.info[k];
77 temporary.
swap(*
this);
90 std::swap(type, other.type);
91 std::swap(info, other.info);
92 data.swap(other.data);
102 data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(std::move(values)));
112 data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(values));
126 for (
int k = 0; k < INFO_COUNT; ++k) {
134 std::size_t dataSize;
136 data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(dataSize));
137 for (std::size_t k = 0; k < dataSize; ++k) {
154 for (
int k = 0; k < INFO_COUNT; ++k) {
158 bool hasData = (data !=
nullptr);
162 std::size_t dataSize = data->size();
164 for (std::size_t k = 0; k < dataSize; ++k) {
214 : m_syncEnabled(false)
216 for (
int k = SYNC_MODE_ITR_BEGIN; k != SYNC_MODE_ITR_END; ++k) {
236 std::swap(other.m_slaves, m_slaves);
237 std::swap(other.m_syncGroups, m_syncGroups);
238 std::swap(other.m_syncJournal, m_syncJournal);
250 throw std::out_of_range(
"Slave is already registered");
257 SyncGroup &syncGroup = m_syncGroups.at(syncMode);
258 syncGroup.push_back(slave);
278 for (
PiercedSyncSlave *slave : m_syncGroups.at(PiercedSyncMaster::SYNC_MODE_CONCURRENT)) {
279 commitSyncAction(slave, action);
284 if (m_syncGroups.at(PiercedSyncMaster::SYNC_MODE_JOURNALED).size() > 0) {
285 journalSyncAction(action);
297 slave->commitSyncAction(action);
305void PiercedSyncMaster::journalSyncAction(
const PiercedSyncAction &action)
308 PiercedSyncAction *previousAction =
nullptr;
309 if (!m_syncJournal.empty()) {
310 previousAction = &(m_syncJournal.back());
314 if (previousAction) {
315 previousActionType = previousAction->type;
321 switch (action.type) {
323 case PiercedSyncAction::TYPE_CLEAR:
324 m_syncJournal.resize(1);
325 m_syncJournal[0] = action;
328 case PiercedSyncAction::TYPE_APPEND:
329 if (previousActionType == PiercedSyncAction::TYPE_APPEND) {
330 previousAction->type = PiercedSyncAction::TYPE_RESIZE;
331 previousAction->info[PiercedSyncAction::INFO_SIZE] = action.info[PiercedSyncAction::INFO_POS] + 1;
332 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
333 }
else if (previousActionType == PiercedSyncAction::TYPE_RESIZE) {
334 previousAction->info[PiercedSyncAction::INFO_SIZE] = action.info[PiercedSyncAction::INFO_POS] + 1;
336 m_syncJournal.push_back(action);
340 case PiercedSyncAction::TYPE_RESIZE:
341 if (previousActionType == PiercedSyncAction::TYPE_APPEND) {
342 previousAction->type = PiercedSyncAction::TYPE_RESIZE;
343 previousAction->info[PiercedSyncAction::INFO_SIZE] = action.info[PiercedSyncAction::INFO_SIZE];
344 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
345 }
else if (previousActionType == PiercedSyncAction::TYPE_RESIZE) {
346 previousAction->info[PiercedSyncAction::INFO_SIZE] = action.info[PiercedSyncAction::INFO_SIZE];
348 m_syncJournal.push_back(action);
352 case PiercedSyncAction::TYPE_PIERCE:
353 if (previousActionType == PiercedSyncAction::TYPE_PIERCE) {
354 previousAction->type = PiercedSyncAction::TYPE_PIERCE_MULTIPLE;
355 previousAction->data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(2));
356 (*(previousAction->data))[0] = previousAction->info[PiercedSyncAction::INFO_POS];
357 (*(previousAction->data))[1] = action.info[PiercedSyncAction::INFO_POS];
358 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
359 previousAction->info[PiercedSyncAction::INFO_POS_NEXT] = std::numeric_limits<std::size_t>::max();
360 }
else if (previousActionType == PiercedSyncAction::TYPE_PIERCE_MULTIPLE) {
361 previousAction->data->push_back(action.info[PiercedSyncAction::INFO_POS]);
363 m_syncJournal.push_back(action);
367 case PiercedSyncAction::TYPE_PIERCE_MULTIPLE:
368 if (previousActionType == PiercedSyncAction::TYPE_PIERCE) {
369 previousAction->type = PiercedSyncAction::TYPE_PIERCE_MULTIPLE;
370 previousAction->data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(action.data->size() + 1));
371 (*(previousAction->data))[0] = previousAction->info[PiercedSyncAction::INFO_POS];
372 previousAction->data->insert(previousAction->data->begin() + 1, action.data->begin(), action.data->end());
373 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
374 previousAction->info[PiercedSyncAction::INFO_POS_NEXT] = std::numeric_limits<std::size_t>::max();
375 }
else if (previousActionType == PiercedSyncAction::TYPE_PIERCE_MULTIPLE) {
376 previousAction->data->insert(previousAction->data->begin(), action.data->begin(), action.data->end());
378 m_syncJournal.push_back(action);
382 case PiercedSyncAction::TYPE_OVERWRITE:
383 if (previousActionType == PiercedSyncAction::TYPE_OVERWRITE) {
384 previousAction->type = PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE;
385 previousAction->data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(2));
386 (*(previousAction->data))[0] = previousAction->info[PiercedSyncAction::INFO_POS];
387 (*(previousAction->data))[1] = action.info[PiercedSyncAction::INFO_POS];
388 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
389 }
else if (previousActionType == PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE) {
390 previousAction->data->push_back(action.info[PiercedSyncAction::INFO_POS]);
392 m_syncJournal.push_back(action);
396 case PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE:
397 if (previousActionType == PiercedSyncAction::TYPE_OVERWRITE) {
398 previousAction->type = PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE;
399 previousAction->data = std::unique_ptr<std::vector<std::size_t>>(
new std::vector<std::size_t>(action.data->size() + 1));
400 (*(previousAction->data))[0] = previousAction->info[PiercedSyncAction::INFO_POS];
401 previousAction->data->insert(previousAction->data->begin() + 1, action.data->begin(), action.data->end());
402 previousAction->info[PiercedSyncAction::INFO_POS] = std::numeric_limits<std::size_t>::max();
403 }
else if (previousActionType == PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE) {
404 previousAction->data->insert(previousAction->data->begin(), action.data->begin(), action.data->end());
406 m_syncJournal.push_back(action);
410 case PiercedSyncAction::TYPE_NOOP:
414 m_syncJournal.push_back(action);
434 SyncGroup &syncGroup = m_syncGroups.at(syncMode);
435 for (
auto itr = syncGroup.begin(); itr != syncGroup.end(); ++itr) {
438 syncGroup.erase(itr);
480 if (syncMode == SYNC_MODE_CONCURRENT) {
482 }
else if (syncMode == SYNC_MODE_JOURNALED) {
483 return m_syncJournal.empty();
497 commitSyncAction(slave, action);
502 m_syncJournal.clear();
503 m_syncJournal.shrink_to_fit();
513 for (
const PiercedSyncSlave *slave : m_syncGroups.at(SYNC_MODE_JOURNALED)) {
530 m_syncEnabled = enabled;
541 return m_syncEnabled;
551 std::size_t journalSize;
553 m_syncJournal.resize(journalSize);
555 action.restore(stream);
566 std::size_t journalSize = m_syncJournal.size();
Action for pierced synchronization.
PiercedSyncAction(ActionType _type=TYPE_UNDEFINED)
void restore(std::istream &stream)
void swap(PiercedSyncAction &other) noexcept
void importData(std::vector< std::size_t > &&values)
void dump(std::ostream &stream) const
PiercedSyncAction & operator=(const PiercedSyncAction &other)
Base class for defining an object that acts like a master in pierced synchronization.
bool isSyncEnabled() const
void restore(std::istream &stream)
PiercedSyncMaster::SyncMode getSlaveSyncMode(const PiercedSyncSlave *slave) const
void setSyncEnabled(bool enabled) const
std::vector< PiercedSyncSlave * > SyncGroup
void unregisterSlave(const PiercedSyncSlave *slave) const
void swap(PiercedSyncMaster &other) noexcept
bool isSlaveRegistered(const PiercedSyncSlave *slave) const
void registerSlave(PiercedSyncSlave *slave, PiercedSyncMaster::SyncMode syncMode) const
void processSyncAction(const PiercedSyncAction &action)
bool isSlaveSynced(const PiercedSyncSlave *slave) const
void dump(std::ostream &stream) const
std::unordered_map< PiercedSyncSlave *, SyncMode > m_slaves
Base class for defining an object that acts like a slave in pierced synchronization.
void swap(PiercedSyncSlave &other) noexcept
void write(std::ostream &stream, const std::vector< bool > &container)
void read(std::istream &stream, std::vector< bool > &container)
#define BITPIT_UNUSED(variable)