row_cache: Clear partitions with region locked

Since invalidate() may allocate, we need to take the region lock to
keep m.partitions references valid around whole clear_and_dispose(),
which relies on that.
This commit is contained in:
Tomasz Grabiec
2016-02-26 16:52:02 +01:00
parent 97558b2cfe
commit be24816c8a
2 changed files with 12 additions and 5 deletions

View File

@@ -443,13 +443,14 @@ future<> row_cache::update(memtable& m, partition_presence_checker presence_chec
auto t = seastar::thread(attr, [this, &m, presence_checker = std::move(presence_checker)] {
auto cleanup = defer([&] {
with_allocator(_tracker.allocator(), [&m, this] () {
logalloc::reclaim_lock _(_tracker.region());
bool blow_cache = false;
// Note: clear_and_dispose() ought not to look up any keys, so it doesn't require
// with_linearized_managed_bytes(), but invalidate() does.
m.partitions.clear_and_dispose([this, deleter = current_deleter<partition_entry>(), &blow_cache] (partition_entry* entry) {
with_linearized_managed_bytes([&] {
try {
invalidate(entry->key());
invalidate_locked(entry->key());
deleter(entry);
} catch (...) {
blow_cache = true;
@@ -541,14 +542,19 @@ void row_cache::touch(const dht::decorated_key& dk) {
});
}
void row_cache::invalidate_locked(const dht::decorated_key& dk) {
_partitions.erase_and_dispose(dk, cache_entry::compare(_schema),
[this, deleter = current_deleter<cache_entry>()](auto&& p) mutable {
_tracker.on_erase();
deleter(p);
});
}
void row_cache::invalidate(const dht::decorated_key& dk) {
_read_section(_tracker.region(), [&] {
with_allocator(_tracker.allocator(), [this, &dk] {
with_linearized_managed_bytes([&] {
_partitions.erase_and_dispose(dk, cache_entry::compare(_schema), [this, deleter = current_deleter<cache_entry>()] (auto&& p) mutable {
_tracker.on_erase();
deleter(p);
});
invalidate_locked(dk);
});
});
});

View File

@@ -199,6 +199,7 @@ private:
void on_hit();
void on_miss();
void upgrade_entry(cache_entry&);
void invalidate_locked(const dht::decorated_key&);
static thread_local seastar::thread_scheduling_group _update_thread_scheduling_group;
public:
~row_cache();