465template<
typename id_t>
477 std::size_t kernelSize = size();
478 std::size_t kernelRawSize = rawSize();
482 syncAction.info[PiercedSyncAction::INFO_SIZE] = kernelSize;
485 std::size_t nHoles = holesCount();
488 syncAction.
importData(std::vector<std::size_t>(kernelRawSize));
489 std::vector<std::size_t> &permutations = *(syncAction.data);
492 std::size_t firstPosToUpdate;
493 if (m_begin_pos == 0) {
494 firstPosToUpdate = m_holes[m_holes_regular_end - 1];
496 firstPosToUpdate = 0;
499 for (std::size_t pos = 0; pos < firstPosToUpdate; ++pos) {
500 permutations[pos] = pos;
503 std::size_t offset = 0;
504 for (std::size_t pos = firstPosToUpdate; pos < m_end_pos; pos++) {
505 if (offset < nHoles && m_holes[m_holes_regular_end - offset - 1] == pos) {
506 permutations[m_end_pos - 1 - offset] = pos;
511 id_t
id = m_ids[pos];
512 std::size_t updatedPos = pos - offset;
514 setPosId(updatedPos,
id);
515 setPosEmptyId(pos, pos + 1);
516 permutations[updatedPos] = pos;
519 for (std::size_t pos = m_end_pos; pos < rawSize(); ++pos) {
520 permutations[pos] = pos;
530 rawShrink(kernelSize);
549template<
typename id_t>
555 processSyncAction(syncAction);
572template<
typename id_t>
576 m_ids.shrink_to_fit();
596template<
typename id_t>
601 std::swap(other.m_begin_pos, m_begin_pos);
602 std::swap(other.m_end_pos, m_end_pos);
603 std::swap(other.m_dirty_begin_pos, m_dirty_begin_pos);
604 std::swap(other.m_ids, m_ids);
605 std::swap(other.m_pos, m_pos);
606 std::swap(other.m_holes, m_holes);
607 std::swap(other.m_holes_regular_begin, m_holes_regular_begin);
608 std::swap(other.m_holes_regular_end, m_holes_regular_end);
609 std::swap(other.m_holes_regular_sorted, m_holes_regular_sorted);
610 std::swap(other.m_holes_pending_begin, m_holes_pending_begin);
611 std::swap(other.m_holes_pending_end, m_holes_pending_end);
612 std::swap(other.m_holes_pending_sorted, m_holes_pending_sorted);
618template<
typename id_t>
628template<
typename id_t>
631 std::cout <<
"----------------[ DUMP ]----------------" << std::endl;
633 std::cout << std::endl;
634 std::cout <<
" size: " << size() << std::endl;
636 std::cout <<
" m_holes_regular_begin: " << m_holes_regular_begin << std::endl;
637 std::cout <<
" m_holes_regular_end : " << m_holes_regular_end << std::endl;
639 std::cout << std::endl;
640 std::cout <<
" Regular holes: " << std::endl;
641 for (std::size_t k = m_holes_regular_begin; k < m_holes_regular_end; ++k) {
642 std::cout << m_holes[k] << std::endl;
645 std::cout << std::endl;
646 std::cout <<
" m_holes_pending_begin: " << m_holes_pending_begin << std::endl;
647 std::cout <<
" m_holes_pending_end : " << m_holes_pending_end << std::endl;
649 std::cout << std::endl;
650 std::cout <<
" Pending holes" << std::endl;
651 for (std::size_t k = m_holes_pending_begin; k < m_holes_pending_end; ++k) {
652 std::cout << m_holes[k] << std::endl;
655 std::cout << std::endl;
656 std::cout <<
" m_begin_pos: " << m_begin_pos << std::endl;
657 std::cout <<
" m_end_pos: " << m_end_pos << std::endl;
658 std::cout <<
" Stored ids: " << std::endl;
660 for (std::size_t k = 0; k < m_end_pos; ++k) {
661 std::cout << m_ids[k] << std::endl;
664 std::cout <<
"None" << std::endl;
667 std::cout << std::endl;
668 std::cout <<
" Poistion map: " << std::endl;
670 for (
auto itr = m_pos.cbegin(); itr != m_pos.cend(); ++itr) {
671 std::cout << itr->first <<
" -> " << itr->second << std::endl;
674 std::cout <<
"None" << std::endl;
677 std::cout <<
"----------------------------------------" << std::endl;
683template<
typename id_t>
687 for (
const auto &entry : m_pos) {
688 id_t
id = entry.first;
689 std::size_t pos = entry.second;
690 if (m_ids[pos] !=
id) {
691 std::cout <<
" Position " << pos <<
" should contain the element with id " <<
id << std::endl;
692 std::cout <<
" but it contains the element with id " << m_ids[pos] << std::endl;
693 throw std::runtime_error(
"Integrity check error");
697 for (std::size_t pos = m_begin_pos; pos < m_end_pos; ++pos) {
698 id_t
id = m_ids[pos];
700 if (m_pos.count(
id) == 0) {
701 std::cout <<
" Position " << pos <<
" contains the element with id " <<
id << std::endl;
702 std::cout <<
" but the position map doesn't contain that element" << std::endl;
703 throw std::runtime_error(
"Integrity check error");
704 }
else if (m_pos.at(
id) != pos) {
705 std::cout <<
" Position " << pos <<
" contains the element with id " <<
id << std::endl;
706 std::cout <<
" but the position map claims that the element is at position " << m_pos.at(
id) << std::endl;
707 throw std::runtime_error(
"Integrity check error");
714 for (
auto it = begin(); it != end(); ++it) {
719 std::cout <<
" The number of elements visited by the iterator doesn't match the size of the kernel" << std::endl;
720 std::cout <<
" The iterator has visited " << n <<
"elements" << std::endl;
721 std::cout <<
" The size of the kernel is " << size() << std::endl;
722 throw std::runtime_error(
"Integrity check error");
733 while (pos < m_ids.size() - 1) {
734 for (std::size_t i = pos; i < m_ids.size(); ++i) {
742 if (m_ids[i + 1] >= 0 && m_ids[i] == - 1) {
748 if ((m_ids[i] - m_ids[i + 1] != -1) && m_ids[i] != -1) {
749 std::cout <<
" The ids associated with empty positions are not consecutive" << std::endl;
750 std::cout <<
" Position " << i <<
" is associated with id " << m_ids[i] << std::endl;
751 std::cout <<
" Position " << (i + 1) <<
" is associated with id " << m_ids[i + 1] << std::endl;
752 throw std::runtime_error(
"Integrity check error");
765template<
typename id_t>
768 return (holesCount() == 0);
776template<
typename id_t>
779 return m_pos.empty();
794template<
typename id_t>
797 return (m_dirty_begin_pos < m_end_pos);
808template<
typename id_t>
811 return m_ids.max_size();
822template<
typename id_t>
836template<
typename id_t>
849template<
typename id_t>
852 return m_ids.capacity();
862template<
typename id_t>
865 return (m_pos.count(
id) != 0);
879template<
typename id_t>
882 return m_pos.count(
id);
890template<
typename id_t>
911template<
typename id_t>
914 std::size_t pos = getPos(
id);
917 std::size_t flat = pos;
920 if (holesCountPending() > 0) {
924 std::size_t nHolesBefore = 0;
925 for (
auto itr = pending_begin_itr; itr != pending_end_itr; ++itr) {
931 flat -= nHolesBefore;
935 if (holesCountRegular() > 0) {
939 std::size_t nHolesBefore = 0;
940 for (
auto itr = regular_begin_itr; itr != regular_end_itr; ++itr) {
946 flat -= nHolesBefore;
960template<
typename id_t>
963 std::size_t nIds = size();
966 std::vector<id_t> ids;
976 std::size_t pos = m_begin_pos;
984 pos = findNextUsedPos(pos);
989 std::sort(ids.begin(), ids.end());
1008template<
typename id_t>
1015 if (targetSize >= size()) {
1017 }
else if (targetSize == 0) {
1018 return m_ids[m_begin_pos];
1019 }
else if (targetSize == (size() - 1)) {
1020 return m_ids[m_end_pos - 1];
1029 holes_iterator regular_begin_itr = m_holes.begin() + m_holes_regular_begin;
1030 holes_iterator regular_hole_itr = m_holes.begin() + m_holes_regular_end;
1032 holes_iterator pending_begin_itr = m_holes.begin() + m_holes_pending_begin;
1033 holes_iterator pending_hole_itr = m_holes.begin() + m_holes_pending_end;
1035 std::size_t nEmpties = 0;
1036 std::size_t markerPos = targetSize;
1038 if (isPosEmpty(markerPos)) {
1039 markerPos = findNextUsedPos(markerPos - 1);
1044 if (regular_hole_itr != regular_begin_itr) {
1046 regular_hole_itr = std::upper_bound(regular_begin_itr, regular_hole_itr, markerPos, std::greater<std::size_t>());
1047 nEmpties += std::distance(regular_hole_itr, itr_previous);
1050 if (pending_hole_itr != pending_begin_itr) {
1052 pending_hole_itr = std::upper_bound(pending_begin_itr, pending_hole_itr, markerPos, std::greater<std::size_t>());
1053 nEmpties += std::distance(pending_hole_itr, itr_previous);
1060 std::size_t markerSize = markerPos - nEmpties;
1061 if (markerSize == targetSize) {
1064 markerPos += targetSize - markerSize;
1068 return m_ids[markerPos];
1077template<
typename id_t>
1080 auto iterator = m_pos.find(
id);
1081 if (iterator != m_pos.end()) {
1082 return rawFind(iterator->second);
1094template<
typename id_t>
1105template<
typename id_t>
1118template<
typename id_t>
1129template<
typename id_t>
1132 return rawFind(m_begin_pos);
1141template<
typename id_t>
1144 return rawFind(m_end_pos);
1155template<
typename id_t>
1158 return m_pos.at(
id);
1168template<
typename id_t>
1172 throw std::out_of_range(
"Vector is empty");
1185template<
typename id_t>
1189 throw std::out_of_range(
"Vector is empty");
1192 return m_end_pos - 1;
1204template<
typename id_t>
1208 if (m_holes_pending_begin != m_holes_pending_end) {
1213 return fillHole(m_holes_pending_end - 1,
id);
1217 if (m_holes_regular_begin != m_holes_regular_end) {
1222 return fillHole(m_holes_regular_end - 1,
id);
1226 return fillAppend(
id);
1237template<
typename id_t>
1241 if (m_holes_pending_begin != m_holes_pending_end) {
1246 return fillHole(m_holes_pending_begin,
id);
1250 if (m_holes_regular_begin != m_holes_regular_end) {
1255 return fillHole(m_holes_regular_begin,
id);
1259 return fillAppend(
id);
1272template<
typename id_t>
1276 std::size_t referencePos = getPos(referenceId);
1279 if (m_holes_pending_begin != m_holes_pending_end) {
1286 std::size_t hole = m_holes_pending_begin;
1287 if (m_holes[hole] > referencePos) {
1288 return fillHole(hole,
id);
1293 if (m_holes_regular_begin != m_holes_regular_end) {
1300 std::size_t hole = m_holes_regular_begin;
1301 if (m_holes[hole] > referencePos) {
1302 return fillHole(hole,
id);
1307 return fillAppend(
id);
1320template<
typename id_t>
1324 std::size_t referencePos = getPos(referenceId);
1327 if (m_holes_pending_begin != m_holes_pending_end) {
1334 std::size_t hole = m_holes_pending_end - 1;
1335 if (m_holes[hole] < referencePos) {
1336 return fillHole(hole,
id);
1341 if (m_holes_regular_begin != m_holes_regular_end) {
1348 std::size_t hole = m_holes_regular_end - 1;
1349 if (m_holes[hole] < referencePos) {
1350 return fillHole(hole,
id);
1355 return fillInsert(referencePos,
id);
1366template<
typename id_t>
1373 m_ids.emplace_back(
id);
1376 setEndPos(rawSize());
1379 m_pos[id] = m_end_pos - 1;
1382 FillAction fillAction(FillAction::TYPE_APPEND);
1383 fillAction.info[PiercedSyncAction::INFO_POS] = m_end_pos - 1;
1384 processSyncAction(fillAction);
1397template<
typename id_t>
1404 std::size_t pos = m_holes[hole];
1410 if (hole >= m_holes_pending_begin) {
1411 int nPendings = holesCountPending();
1412 if (nPendings > 1) {
1413 if (hole == (m_holes_pending_end - 1)) {
1414 --m_holes_pending_end;
1415 }
else if (hole == m_holes_pending_begin) {
1416 ++m_holes_pending_begin;
1418 throw std::out_of_range(
"Only holes at the beginning or at the end of the kernel can be filled");
1421 holesClearPending();
1424 int nRegulars = holesCountRegular();
1425 if (nRegulars > 1) {
1426 if (hole == (m_holes_regular_end - 1)) {
1427 --m_holes_regular_end;
1428 }
else if (hole == m_holes_regular_begin) {
1429 ++m_holes_regular_begin;
1431 throw std::out_of_range(
"Only holes at the beginning or at the end of the kernel can be filled");
1434 holesClearRegular();
1442 if (pos < m_begin_pos) {
1451 std::size_t previousPos = pos;
1452 while (previousPos > 0) {
1454 if (!isPosEmpty(previousPos)) {
1458 id_t previousId = m_ids[previousPos];
1459 if (previousId == -1 || (std::size_t) std::abs(previousId) == (pos - previousPos)) {
1463 setPosEmptyId(previousPos, pos);
1467 FillAction fillAction(FillAction::TYPE_OVERWRITE);
1468 fillAction.info[PiercedSyncAction::INFO_POS] = pos;
1469 processSyncAction(fillAction);
1484template<
typename id_t>
1490 if (isPosEmpty(pos)) {
1491 throw std::out_of_range(
"Before inserting a new position the hole needs to be filled first");
1495 if (pos >= m_end_pos) {
1496 throw std::out_of_range(
"Unable to insert elements past the last position");
1503 m_ids.emplace(m_ids.begin() + pos,
id);
1506 setEndPos(rawSize());
1509 for (std::size_t i = pos + 1; i < m_end_pos; ++i) {
1510 id_t id_i = m_ids[i];
1518 if (m_holes_regular_begin != m_holes_regular_end) {
1519 holes_iterator regular_begin_itr = m_holes.begin() + m_holes_regular_begin;
1520 holes_iterator regular_end_itr = m_holes.begin() + m_holes_regular_end;
1523 holes_iterator update_end_itr = upper_bound(regular_begin_itr, regular_end_itr, pos, std::greater<std::size_t>());
1524 for (
auto itr = update_begin_itr; itr != update_end_itr; itr++) {
1530 if (m_holes_pending_begin != m_holes_pending_end) {
1531 holes_iterator pending_begin_itr = m_holes.begin() + m_holes_pending_begin;
1532 holes_iterator pending_end_itr = m_holes.begin() + m_holes_pending_end;
1535 holes_iterator update_end_itr = upper_bound(pending_begin_itr, pending_end_itr, pos, std::greater<std::size_t>());
1536 for (
auto itr = update_begin_itr; itr != update_end_itr; itr++) {
1542 FillAction fillAction(FillAction::TYPE_INSERT);
1543 fillAction.info[PiercedSyncAction::INFO_POS] = pos;
1544 processSyncAction(fillAction);
1559template<
typename id_t>
1562 assert(referenceId !=
id);
1565 bool syncEnabled = isSyncEnabled();
1567 setSyncEnabled(
false);
1571 std::size_t initialPos = getPos(
id);
1572 pierce(initialPos, flush);
1575 FillAction fillAction = fillAfter(referenceId,
id);
1579 setSyncEnabled(
true);
1583 typename MoveAction::MoveActionType moveActionType;
1584 switch (
static_cast<typename FillAction::FillActionType
>(fillAction.type)) {
1586 case FillAction::TYPE_APPEND:
1587 moveActionType = MoveAction::TYPE_APPEND;
1590 case FillAction::TYPE_INSERT:
1591 moveActionType = MoveAction::TYPE_INSERT;
1594 case FillAction::TYPE_OVERWRITE:
1595 moveActionType = MoveAction::TYPE_OVERWRITE;
1600 moveActionType = MoveAction::TYPE_UNDEFINED;
1606 moveAction.info[PiercedSyncAction::INFO_POS_FIRST] = initialPos;
1607 moveAction.info[PiercedSyncAction::INFO_POS_SECOND] = fillAction.info[PiercedSyncAction::INFO_POS];
1608 processSyncAction(moveAction);
1623template<
typename id_t>
1626 assert(referenceId !=
id);
1629 bool syncEnabled = isSyncEnabled();
1631 setSyncEnabled(
false);
1635 std::size_t initialPos = getPos(
id);
1636 pierce(initialPos, flush);
1639 FillAction fillAction = fillBefore(referenceId,
id);
1643 setSyncEnabled(
true);
1647 typename MoveAction::MoveActionType moveActionType;
1648 switch (
static_cast<typename FillAction::FillActionType
>(fillAction.type)) {
1650 case FillAction::TYPE_APPEND:
1651 moveActionType = MoveAction::TYPE_APPEND;
1654 case FillAction::TYPE_INSERT:
1655 moveActionType = MoveAction::TYPE_INSERT;
1658 case FillAction::TYPE_OVERWRITE:
1659 moveActionType = MoveAction::TYPE_OVERWRITE;
1664 moveActionType = MoveAction::TYPE_UNDEFINED;
1670 moveAction.info[PiercedSyncAction::INFO_POS_FIRST] = initialPos;
1671 moveAction.info[PiercedSyncAction::INFO_POS_SECOND] = fillAction.info[PiercedSyncAction::INFO_POS];
1672 processSyncAction(moveAction);
1685template<
typename id_t>
1689 std::size_t pos_first = m_pos.at(id_first);
1690 std::size_t pos_second = m_pos.at(id_second);
1693 swapPosIds(pos_first, id_first, pos_second, id_second);
1696 SwapAction swapAction(SwapAction::TYPE_SWAP);
1697 swapAction.info[PiercedSyncAction::INFO_POS_FIRST] = pos_first;
1698 swapAction.info[PiercedSyncAction::INFO_POS_SECOND] = pos_second;
1699 processSyncAction(swapAction);
1716template<
typename id_t>
1720 std::size_t pos = m_pos.at(
id);
1726 if (pos + 1 < m_end_pos) {
1727 EraseAction pierceAction(EraseAction::TYPE_PIERCE);
1728 pierceAction.info[PiercedSyncAction::INFO_POS] = pos;
1729 pierceAction.info[PiercedSyncAction::INFO_POS_NEXT] = findNextUsedPos(pos);
1730 processSyncAction(pierceAction);
1732 return pierceAction;
1734 EraseAction resizeAction(EraseAction::TYPE_SHRINK);
1735 resizeAction.info[PiercedSyncAction::INFO_SIZE] = rawSize();
1736 processSyncAction(resizeAction);
1738 return resizeAction;
1750template<
typename id_t>
1755 throw std::out_of_range(
"Vector is empty");
1759 std::size_t updatedRawSize;
1763 updatedRawSize = findPrevUsedPos(m_end_pos - 1) + 1;
1766 rawShrink(updatedRawSize);
1769 EraseAction eraseAction(EraseAction::TYPE_SHRINK);
1770 eraseAction.info[PiercedSyncAction::INFO_SIZE] = rawSize();
1771 processSyncAction(eraseAction);
1787template<
typename id_t>
1793 if (pos + 1 == m_end_pos) {
1794 std::size_t updatedRawSize;
1798 updatedRawSize = findPrevUsedPos(m_end_pos - 1) + 1;
1801 rawShrink(updatedRawSize);
1807 id_t
id = m_ids[pos];
1811 std::size_t nextUsedPos = findNextUsedPos(pos);
1812 setPosEmptyId(pos, nextUsedPos);
1813 m_dirty_begin_pos = std::min(pos, m_dirty_begin_pos);
1816 if (pos == m_begin_pos) {
1817 std::size_t begin = findNextUsedPos(m_begin_pos);
1822 if (m_holes_pending_end == m_holes.size()) {
1827 m_holes[m_holes_pending_end] = pos;
1828 m_holes_pending_end++;
1831 if (m_holes_pending_sorted) {
1832 std::size_t nPendings = holesCountPending();
1833 if (nPendings > 1 && (m_holes[m_holes_pending_end - 1] > m_holes[m_holes_pending_end - 2])) {
1834 m_holes_pending_sorted =
false;
1850template<
typename id_t>
1851void PiercedKernel<id_t>::holesClear(
bool release)
1854 holesResize(0, 0, 0, release);
1857 m_holes_regular_sorted =
true;
1858 m_holes_pending_sorted =
true;
1867template<
typename id_t>
1868void PiercedKernel<id_t>::holesClearRegular(
bool release)
1872 m_holes.shrink_to_fit();
1876 m_holes_regular_begin = 0;
1877 m_holes_regular_end = m_holes_regular_begin;
1880 m_holes_regular_sorted =
true;
1889template<
typename id_t>
1890void PiercedKernel<id_t>::holesClearPending(
bool release)
1893 long offset = m_holes_regular_begin;
1894 long nRegulars = holesCountRegular();
1895 holesResize(offset, nRegulars, 0, release);
1898 m_holes_pending_sorted =
true;
1911template<
typename id_t>
1912void PiercedKernel<id_t>::holesResize(std::size_t offset, std::size_t nRegulars, std::size_t nPendings,
bool release)
1915 m_holes.shrink_to_fit();
1918 m_holes.resize(offset + nRegulars + MAX_PENDING_HOLES);
1920 m_holes_regular_begin = offset;
1921 m_holes_regular_end = m_holes_regular_begin + nRegulars;
1922 m_holes_pending_begin = m_holes_regular_end;
1923 m_holes_pending_end = m_holes_pending_begin + nPendings;
1931template<
typename id_t>
1932std::size_t PiercedKernel<id_t>::holesCount()
const
1934 return holesCountPending() + holesCountRegular();
1942template<
typename id_t>
1943std::size_t PiercedKernel<id_t>::holesCountPending()
const
1945 return (m_holes_pending_end - m_holes_pending_begin);
1953template<
typename id_t>
1954std::size_t PiercedKernel<id_t>::holesCountRegular()
const
1956 return (m_holes_regular_end - m_holes_regular_begin);
1967template<
typename id_t>
1968void PiercedKernel<id_t>::holesFlush()
1971 if (m_holes_pending_begin == m_holes_pending_end) {
1985 std::size_t hole = m_holes_pending_begin;
1986 std::size_t pos = m_end_pos;
1988 if (m_holes[hole] >= pos) {
1993 pos = m_holes[hole];
1994 std::size_t next_used_pos = findNextUsedPos(pos);
1996 setPosEmptyId(pos, next_used_pos);
2002 }
while (isPosEmpty(pos));
2003 }
while (pos > 0 && hole != m_holes_pending_end);
2006 for (std::size_t hole = m_holes_pending_begin; hole < m_holes_pending_end; ++hole) {
2007 std::size_t pos = m_holes[hole];
2011 if (m_holes_regular_begin != 0) {
2012 --m_holes_regular_begin;
2013 m_holes[m_holes_regular_begin] = pos;
2016 if (m_holes_regular_sorted) {
2017 m_holes_regular_sorted =
false;
2020 if (hole != m_holes_regular_end) {
2021 m_holes[m_holes_regular_end] = pos;
2023 ++m_holes_regular_end;
2024 ++m_holes_pending_begin;
2027 if (m_holes_regular_sorted) {
2028 std::size_t nRegulars = holesCountRegular();
2029 if (nRegulars > 1 && (m_holes[m_holes_regular_end - 1] > m_holes[m_holes_regular_end - 2])) {
2030 m_holes_regular_sorted =
false;
2037 std::size_t nRegulars = holesCountRegular();
2038 if (nRegulars != 0 && m_holes_regular_begin != 0) {
2039 for (std::size_t k = 0; k < nRegulars; ++k) {
2040 m_holes[k] = m_holes[m_holes_regular_begin + k];
2043 m_holes_regular_begin = 0;
2044 m_holes_regular_end = m_holes_regular_begin + nRegulars;
2048 holesClearPending();
2051 m_dirty_begin_pos = m_end_pos;
2058template<
typename id_t>
2059void PiercedKernel<id_t>::holesSortPending()
2061 if (m_holes_pending_sorted) {
2065 holes_iterator pending_begin_itr = m_holes.begin() + m_holes_pending_begin;
2066 holes_iterator pending_end_itr = m_holes.begin() + m_holes_pending_end;
2067 std::sort(pending_begin_itr, pending_end_itr, std::greater<std::size_t>());
2068 m_holes_pending_sorted =
true;
2074template<
typename id_t>
2075void PiercedKernel<id_t>::holesSortRegular()
2077 if (m_holes_regular_sorted) {
2081 holes_iterator regular_begin_itr = m_holes.begin() + m_holes_regular_begin;
2082 holes_iterator regular_end_itr = m_holes.begin() + m_holes_regular_end;
2083 std::sort(regular_begin_itr, regular_end_itr, std::greater<std::size_t>());
2084 m_holes_regular_sorted =
true;
2093template<
typename id_t>
2094bool PiercedKernel<id_t>::validateId(id_t
id)
2098 throw std::out_of_range(
"Negative id");
2103 throw std::out_of_range(
"Duplicate id");
2116template<
typename id_t>
2120 throw std::out_of_range(
"Vector is empty");
2123 return (m_end_pos - 1);
2132template<
typename id_t>
2136 throw std::out_of_range(
"Vector is empty");
2147template<
typename id_t>
2150 std::size_t storageIdx = 0;
2151 std::vector<PiercedStorageSyncSlave<id_t> *> storges(m_slaves.size());
2152 for (
auto &slaveEntry : m_slaves) {
2155 if (piercedStorage) {
2156 storges[storageIdx] = piercedStorage;
2169template<
typename id_t>
2172 std::size_t storageIdx = 0;
2173 std::vector<PiercedStorageSyncSlave<id_t> *> storges(m_slaves.size());
2174 for (
const auto &slaveEntry : m_slaves) {
2177 if (piercedStorage) {
2178 storges[storageIdx] = piercedStorage;
2195template<
typename id_t>
2198 std::size_t prev_pos = pos;
2200 if (prev_pos == m_begin_pos) {
2201 throw std::out_of_range(
"Already in the firts position");
2205 id_t prev_id = m_ids[prev_pos];
2220template<
typename id_t>
2223 std::size_t next_pos = pos;
2224 std::size_t next_delta = 1;
2226 if (next_pos + 1 == m_end_pos) {
2227 throw std::out_of_range(
"Already in the last position");
2229 next_pos += next_delta;
2231 id_t next_id = m_ids[next_pos];
2235 next_delta = - next_id;
2249template<
typename id_t>
2252 return (m_ids[pos] < 0);
2261template<
typename id_t>
2281template<
typename id_t>
2282void PiercedKernel<id_t>::setPosEmptyId(std::size_t pos, std::size_t nextUsedPos)
2284 assert(nextUsedPos > pos);
2290 if (pos == (m_end_pos - 1)) {
2291 m_ids[pos] = id_t(-1);
2310 id_t offset = id_t(pos - nextUsedPos);
2311 if (m_ids[pos + 1] == offset + 1) {
2312 m_ids[pos] = offset;
2314 m_ids[pos] = id_t(-1);
2326template<
typename id_t>
2327void PiercedKernel<id_t>::swapPosIds(std::size_t pos_1, id_t id_1, std::size_t pos_2, id_t id_2)
2329 std::swap(m_ids[pos_1], m_ids[pos_2]);
2330 std::swap(m_pos[id_1], m_pos[id_2]);
2336template<
typename id_t>
2337void PiercedKernel<id_t>::setBeginPos(std::size_t pos)
2345template<
typename id_t>
2346void PiercedKernel<id_t>::setEndPos(std::size_t pos)
2356template<
typename id_t>
2357void PiercedKernel<id_t>::rawShrink(std::size_t n)
2360 if (n > m_end_pos) {
2361 throw std::out_of_range(
"The kernel can only be shrunk");
2365 if (n == m_end_pos) {
2371 if (n < (m_begin_pos + 1)) {
2377 for (std::size_t pos = n; pos < m_end_pos; ++pos) {
2378 id_t
id = m_ids[pos];
2391 if (holesCount() != 0) {
2394 holes_iterator regular_begin_itr = m_holes.begin() + m_holes_regular_begin;
2395 holes_iterator regular_end_itr = m_holes.begin() + m_holes_regular_end;
2396 regular_begin_itr = std::lower_bound(regular_begin_itr, regular_end_itr, m_end_pos - 1, std::greater<std::size_t>());
2397 m_holes_regular_begin = std::distance(m_holes.begin(), regular_begin_itr);
2398 if (m_holes_regular_begin == m_holes_regular_end) {
2399 m_holes_regular_begin = 0;
2400 m_holes_regular_end = m_holes_regular_begin;
2405 holes_iterator pending_begin_itr = m_holes.begin() + m_holes_pending_begin;
2406 holes_iterator pending_end_itr = m_holes.begin() + m_holes_pending_end;
2407 pending_begin_itr = std::lower_bound(pending_begin_itr, pending_end_itr, m_end_pos - 1, std::greater<std::size_t>());
2408 m_holes_pending_begin = std::distance(m_holes.begin(), pending_begin_itr);
2409 if (m_holes_pending_begin == m_holes_pending_end) {
2410 m_holes_pending_begin = m_holes_regular_end;
2411 m_holes_pending_end = m_holes_pending_begin;
2421template<
typename id_t>
2427 m_pos.reserve(nIds);
2428 for (std::size_t n = 0; n < nIds; ++n) {
2435 m_pos.insert({id, pos});
2439 std::size_t nPositions;
2441 m_ids.resize(nPositions);
2442 for (std::size_t n = 0; n < nPositions; ++n) {
2456 m_holes.resize(nHoles);
2457 for (std::size_t n = 0; n < nHoles; ++n) {
2480template<
typename id_t>
2484 std::size_t nIds = m_pos.size();
2486 for (
const auto &entry : m_pos) {
2492 std::size_t nPositions = m_ids.size();
2494 for (std::size_t pos : m_ids) {
2503 std::size_t nHoles = m_holes.size();
2505 for (std::size_t hole : m_holes) {