Files
scylladb/mutation_cleaner.hh
Tomasz Grabiec e0803ff71e Introduce mutation_cleaner
Used for collecting unsued partition_version objects and freeing them
incrementally. Will be used for both cache and memtables.
2018-05-30 14:41:39 +02:00

85 lines
2.8 KiB
C++

/*
* Copyright (C) 2018 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 "partition_version.hh"
#include "partition_version_list.hh"
#include "utils/logalloc.hh"
// Container for garbage partition_version objects, used for freeing them incrementally.
class mutation_cleaner final {
logalloc::region& _region;
cache_tracker* _tracker;
partition_version_list _versions;
public:
mutation_cleaner(logalloc::region& r, cache_tracker* t) : _region(r), _tracker(t) {}
~mutation_cleaner();
// Frees some of the data. Returns stop_iteration::yes iff all was freed.
// Must be invoked under owning allocator.
stop_iteration clear_gently() noexcept;
// Must be invoked under owning allocator.
memory::reclaiming_result clear_some() noexcept;
// Must be invoked under owning allocator.
void clear() noexcept;
// Enqueues v for destruction.
// The object must not be part of any list, and must not be accessed externally any more.
// In particular, it must not be attached, even indirectly, to any snapshot or partition_entry,
// and must not be evicted from.
// Must be invoked under owning allocator.
void destroy_later(partition_version& v) noexcept;
// Destroys v now or later.
// Same requirements as destroy_later().
// Must be invoked under owning allocator.
void destroy_gently(partition_version& v) noexcept;
// Transfers objects from other to this.
// This and other must belong to the same logalloc::region, and the same cache_tracker.
// After the call bool(other) is false.
void merge(mutation_cleaner& other) noexcept;
// Returns true iff contains no unfreed objects
bool empty() const noexcept { return _versions.empty(); }
// Forces cleaning and returns a future which resolves when there is nothing to clean.
future<> drain();
};
inline
void mutation_cleaner::destroy_later(partition_version& v) noexcept {
_versions.push_back(v);
}
inline
void mutation_cleaner::destroy_gently(partition_version& v) noexcept {
if (v.clear_gently(_tracker) == stop_iteration::no) {
destroy_later(v);
} else {
current_allocator().destroy(&v);
}
}