save and load functions for the large_bitset were introduced by Avi with
d590e327c0.
In that commit, Avi says:
"... providing iterator-based load() and save() methods. The methods
support partial load/save so that access to very large bitmaps can be
split over multiple tasks."
The only user of this interface is SSTables. And turns out we don't really
split the access like that. What we do instead is to create a chunked vector
and then pass its begin() method with position = 0 and let it write everything.
The problem here is that this require the chunked vector to be fully
initialized, not just reserved. If the bitmap is large enough that in itself
can take a long time without yielding (up to 16ms seen in my setup).
We can simplify things considerably by moving the large_bitset to use a
chunked vector internally: it already uses a poor man's version of it
by allocating chunks internally (it predates the chunked_vector).
By doing that, we can turn save() into a simple copy operation, and do
away with load altogether by adding a new constructor that will just
copy an existing chunked_vector.
Fixes #3341
Tests: unit (release)
Signed-off-by: Glauber Costa <glauber@scylladb.com>
Message-Id: <20180409234726.28219-1-glauber@scylladb.com>
54 lines
1.4 KiB
C++
54 lines
1.4 KiB
C++
/*
|
|
* Copyright (C) 2015 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/>.
|
|
*/
|
|
|
|
#include "large_bitset.hh"
|
|
#include <algorithm>
|
|
#include <seastar/core/align.hh>
|
|
#include <seastar/core/thread.hh>
|
|
#include "seastarx.hh"
|
|
|
|
using namespace seastar;
|
|
|
|
large_bitset::large_bitset(size_t nr_bits) : _nr_bits(nr_bits) {
|
|
assert(thread::running_in_thread());
|
|
|
|
size_t nr_ints = align_up(nr_bits, bits_per_int()) / bits_per_int();
|
|
_storage.reserve(nr_ints);
|
|
while (nr_ints) {
|
|
_storage.push_back(0);
|
|
--nr_ints;
|
|
if (need_preempt()) {
|
|
thread::yield();
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
large_bitset::clear() {
|
|
assert(thread::running_in_thread());
|
|
for (auto&& pos: _storage) {
|
|
pos = 0;
|
|
if (need_preempt()) {
|
|
thread::yield();
|
|
}
|
|
}
|
|
}
|