mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Merge pull request #50059 from ClickHouse/cache-try-reserver-cleanup
FileCache: simple tryReserve() cleanup
This commit is contained in:
commit
945673565c
@ -528,7 +528,7 @@ KeyMetadata::iterator FileCache::addFileSegment(
|
||||
}
|
||||
}
|
||||
|
||||
bool FileCache::tryReserve(FileSegment & file_segment, size_t size)
|
||||
bool FileCache::tryReserve(FileSegment & file_segment, const size_t size)
|
||||
{
|
||||
assertInitialized();
|
||||
auto cache_lock = cache_guard.lock();
|
||||
@ -573,27 +573,26 @@ bool FileCache::tryReserve(FileSegment & file_segment, size_t size)
|
||||
else
|
||||
queue_size += 1;
|
||||
|
||||
class EvictionCandidates final : public std::vector<FileSegmentMetadataPtr>
|
||||
struct EvictionCandidates
|
||||
{
|
||||
public:
|
||||
explicit EvictionCandidates(KeyMetadataPtr key_metadata_) : key_metadata(key_metadata_) {}
|
||||
|
||||
KeyMetadata & getMetadata() { return *key_metadata; }
|
||||
|
||||
void add(FileSegmentMetadataPtr candidate)
|
||||
{
|
||||
candidate->removal_candidate = true;
|
||||
push_back(candidate);
|
||||
candidates.push_back(candidate);
|
||||
}
|
||||
|
||||
~EvictionCandidates()
|
||||
{
|
||||
for (const auto & candidate : *this)
|
||||
/// If failed to reserve space, we don't delete the candidates but drop the flag instead
|
||||
/// so the segments can be used again
|
||||
for (const auto & candidate : candidates)
|
||||
candidate->removal_candidate = false;
|
||||
}
|
||||
|
||||
private:
|
||||
KeyMetadataPtr key_metadata;
|
||||
std::vector<FileSegmentMetadataPtr> candidates;
|
||||
};
|
||||
|
||||
std::unordered_map<Key, EvictionCandidates> to_delete;
|
||||
@ -681,22 +680,25 @@ bool FileCache::tryReserve(FileSegment & file_segment, size_t size)
|
||||
|
||||
for (auto & [current_key, deletion_info] : to_delete)
|
||||
{
|
||||
auto locked_key = deletion_info.getMetadata().tryLock();
|
||||
auto locked_key = deletion_info.key_metadata->tryLock();
|
||||
if (!locked_key)
|
||||
continue; /// key could become invalid after we released the key lock above, just skip it.
|
||||
|
||||
for (auto it = deletion_info.begin(); it != deletion_info.end();)
|
||||
/// delete from vector in reverse order just for efficiency
|
||||
auto & candidates = deletion_info.candidates;
|
||||
while (!candidates.empty())
|
||||
{
|
||||
chassert((*it)->releasable());
|
||||
auto & candidate = candidates.back();
|
||||
chassert(candidate->releasable());
|
||||
|
||||
auto segment = (*it)->file_segment;
|
||||
const auto * segment = candidate->file_segment.get();
|
||||
locked_key->removeFileSegment(segment->offset(), segment->lock());
|
||||
segment->getQueueIterator()->remove(cache_lock);
|
||||
|
||||
if (query_context)
|
||||
query_context->remove(current_key, segment->offset(), cache_lock);
|
||||
|
||||
it = deletion_info.erase(it);
|
||||
candidates.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ struct FileSegmentMetadata : private boost::noncopyable
|
||||
|
||||
bool valid() const { return !removal_candidate.load(); }
|
||||
|
||||
Priority::Iterator getQueueIterator() { return file_segment->getQueueIterator(); }
|
||||
Priority::Iterator getQueueIterator() const { return file_segment->getQueueIterator(); }
|
||||
|
||||
FileSegmentPtr file_segment;
|
||||
std::atomic<bool> removal_candidate{false};
|
||||
|
Loading…
Reference in New Issue
Block a user