Skip to content

Commit

Permalink
GH-5 Fix for remove_indexes already reversed
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed May 14, 2024
1 parent 08dbf43 commit 81c1f44
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
21 changes: 11 additions & 10 deletions libraries/libfc/include/fc/container/ordered_diff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,17 @@ class ordered_diff {
// update move indexes
if (!result.move_indexes.empty()) {
// remove decreases `from` index
auto m = result.move_indexes.begin();
for (auto ritr = result.remove_indexes.rbegin(); ritr != result.remove_indexes.rend(); ++ritr) {
m = std::lower_bound(m, result.move_indexes.end(), *ritr, [&](const auto& p, const auto& v) { return p.first < v; });
for (auto i = m; i != result.move_indexes.end(); ++i) {
--i->first;
for (const auto& i : result.remove_indexes) {
auto m = std::lower_bound(result.move_indexes.begin(), result.move_indexes.end(), i, [&](const auto& p, const auto& v) { return p.first < v; });
for (; m != result.move_indexes.end(); ++m) {
--m->first;
}
}
// insert increases `from` index
m = result.move_indexes.begin();
for (const auto& i : result.insert_indexes) {
m = std::lower_bound(m, result.move_indexes.end(), i.first, [](const auto& p, const auto& v) { return p.first < v; });
for (auto i = m; i != result.move_indexes.end(); ++i) {
++i->first;
auto m = std::lower_bound(result.move_indexes.begin(), result.move_indexes.end(), i.first, [](const auto& p, const auto& v) { return p.first < v; });
for (; m != result.move_indexes.end(); ++m) {
++m->first;
}
}
// remove any moves that are not needed, from == to
Expand All @@ -142,12 +140,15 @@ class ordered_diff {
template <typename X>
requires std::same_as<std::decay_t<X>, diff_result>
static Container<T> apply_diff(Container<T>&& container, X&& diff) {
// Remove from the container based on diff.remove_indexes
// Remove from the container based on diff.remove_indexes which is descending order
for (auto index : diff.remove_indexes) {
container.erase(container.begin() + index);
}

// Insert into the container based on diff.insert_indexes
if constexpr (requires(Container<T>& t) { t.reserve(0u); }) {
container.reserve(container.size() + diff.insert_indexes.size());
}
for (auto&& [index, value] : diff.insert_indexes) {
container.insert(container.begin() + index, std::move(value));
}
Expand Down
37 changes: 37 additions & 0 deletions libraries/libfc/test/test_ordered_diff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,22 @@ BOOST_AUTO_TEST_CASE(ordered_diff_test) try {
source = ordered_diff<char>::apply_diff(std::move(source), result);
BOOST_TEST(source == target);
}
{ // remove odd
vector<char> source = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
vector<char> target = {'b', 'd', 'f', 'h'};
auto result = ordered_diff<char>::diff(source, target);
verify_inserted(result, std::vector<char>{});
source = ordered_diff<char>::apply_diff(std::move(source), result);
BOOST_TEST(source == target);
}
{ // remove even
vector<char> source = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
vector<char> target = {'a', 'c', 'e', 'g'};
auto result = ordered_diff<char>::diff(source, target);
verify_inserted(result, std::vector<char>{});
source = ordered_diff<char>::apply_diff(std::move(source), result);
BOOST_TEST(source == target);
}
{ // non-unique
vector<char> source = {'a', 'b', 'c', 'd', 'e', 'c', 'a', 'q'};
vector<char> target = {'z', 'a', 'b', 'c', 'd', 'a'};
Expand Down Expand Up @@ -305,6 +321,27 @@ BOOST_AUTO_TEST_CASE(ordered_diff_string_test) try {
source = ordered_diff<string>::apply_diff(std::move(source), std::move(result));
BOOST_TEST(source == target);
}
{
vector<string> source = {
"inita", "initb", "initc", "initd", "inite", "initf", "initg",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"};
vector<string> target = { source[3], source[6], source[9], source[12], source[15], source[18], source[20] };
auto result = ordered_diff<string>::diff(source, target);
source = ordered_diff<string>::apply_diff(std::move(source), std::move(result));
BOOST_TEST(source == target);
}
{
vector<string> source = {
"inita", "initb", "initc", "initd", "inite", "initf", "initg",
"inith", "initi", "initj", "initk", "initl", "initm", "initn",
"inito", "initp", "initq", "initr", "inits", "initt", "initu"};
vector<string> target = { source[3], source[6] };
auto result = ordered_diff<string>::diff(source, target);
source = ordered_diff<string>::apply_diff(std::move(source), std::move(result));
BOOST_TEST(source == target);
}


} FC_LOG_AND_RETHROW();

Expand Down

0 comments on commit 81c1f44

Please sign in to comment.