Files
scylladb/utils/stall_free.hh
Asias He 3e8c4a6788 utils: Add clear_gently
A helper to clear a list without stall.

Refs #6975
Refs #6940
2020-08-11 19:37:47 +08:00

72 lines
2.1 KiB
C++

/*
* Copyright (C) 2020 ScyllaDB
*/
/*
* This file is part of Scylla.
*
* Scylla is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Scylla is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <list>
#include <algorithm>
#include <seastar/core/thread.hh>
#include <seastar/core/future.hh>
#include <seastar/core/future-util.hh>
#include "utils/collection-concepts.hh"
namespace utils {
// Similar to std::merge but it does not stall. Must run inside a seastar
// thread. It merges items from list2 into list1. Items from list2 can only be copied.
template<class T, class Compare>
SEASTAR_CONCEPT(requires LessComparable<T, T, Compare>)
void merge_to_gently(std::list<T>& list1, const std::list<T>& list2, Compare comp) {
auto first1 = list1.begin();
auto first2 = list2.begin();
auto last1 = list1.end();
auto last2 = list2.end();
while (first2 != last2) {
seastar::thread::maybe_yield();
if (first1 == last1) {
// Copy remaining items of list2 into list1
std::copy_if(first2, last2, std::back_inserter(list1), [] (const auto&) { return true; });
return;
}
if (comp(*first2, *first1)) {
first1 = list1.insert(first1, *first2);
++first2;
} else {
++first1;
}
}
}
template<class T>
seastar::future<> clear_gently(std::list<T>& list) {
return repeat([&list] () mutable {
if (list.empty()) {
return seastar::stop_iteration::yes;
}
list.pop_back();
return seastar::stop_iteration::no;
});
}
}