1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_DISK_CACHE_SQL_EVICTION_CANDIDATE_AGGREGATOR_H_
#define NET_DISK_CACHE_SQL_EVICTION_CANDIDATE_AGGREGATOR_H_
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "net/base/net_export.h"
#include "net/disk_cache/sql/sql_persistent_store.h"
namespace disk_cache {
// `EvictionCandidateAggregator` is a thread-safe class responsible for
// collecting eviction candidates from multiple shards, aggregating them, and
// then selecting which entries to evict based on the least recently used
// policy.
class NET_EXPORT_PRIVATE EvictionCandidateAggregator
: public base::RefCountedThreadSafe<EvictionCandidateAggregator> {
public:
struct NET_EXPORT_PRIVATE EvictionCandidate {
EvictionCandidate(SqlPersistentStore::ResId res_id,
SqlPersistentStore::ShardId shard_id,
int64_t bytes_usage,
base::Time last_used);
~EvictionCandidate();
EvictionCandidate(EvictionCandidate&&);
EvictionCandidate& operator=(EvictionCandidate&&);
SqlPersistentStore::ResId res_id;
SqlPersistentStore::ShardId shard_id;
int64_t bytes_usage;
base::Time last_used;
};
using EvictionCandidateList = std::vector<EvictionCandidate>;
using EvictionCandidateSelectedCallback =
base::OnceCallback<void(std::vector<SqlPersistentStore::ResId>,
int64_t bytes_usage,
base::TimeTicks post_task_time)>;
explicit EvictionCandidateAggregator(
int64_t size_to_be_removed,
std::vector<scoped_refptr<base::SequencedTaskRunner>> task_runners);
// Called by each shard to provide its list of eviction candidates on the task
// runner assigned to the shard.
// Once all shards have reported, this aggregates the candidates, selects
// entries for eviction, and invokes `selected_callback` for each shard on its
// corresponding SequencedTaskRunner from the `task_runners` vector passed to
// the constructor. The callback for the *last* reporting shard is run
// synchronously within this call, while others are posted as tasks.
void OnCandidate(SqlPersistentStore::ShardId shard_id,
EvictionCandidateList candidate,
EvictionCandidateSelectedCallback selected_callback);
private:
friend class base::RefCountedThreadSafe<EvictionCandidateAggregator>;
~EvictionCandidateAggregator();
// Safely adds a shard's candidates to the aggregation. Once all shards have
// reported, returns true and the collected candidates and callbacks are moved
// into `candidates_per_shard_out` and `selected_callbacks_out`.
bool AddCandidates(
SqlPersistentStore::ShardId shard_id,
EvictionCandidateList new_candidates,
EvictionCandidateSelectedCallback new_selected_callback,
std::vector<EvictionCandidateList>& candidates_per_shard_out,
std::vector<EvictionCandidateSelectedCallback>& selected_callbacks_out);
// Aggregates candidates from all shards, sorts them by last-used time,
// selects entries for eviction, and then posts tasks back to each shard with
// the list of entries to be deleted.
void AggregateCandidatesAndRunCallbacks(
std::vector<EvictionCandidateList> candidates_per_shard,
std::vector<EvictionCandidateSelectedCallback> selected_callbacks,
SqlPersistentStore::ShardId last_shard_id);
size_t GetSizeOfShards() const;
// The total size of entries to be removed.
const int64_t size_to_be_removed_;
// The task runners for each shard, used to post back the eviction tasks.
const std::vector<scoped_refptr<base::SequencedTaskRunner>> task_runners_;
// Protects access to `candidates_per_shard_` and `selected_callbacks_`.
base::Lock lock_;
// A list of eviction candidates from each shard. This is not ordered by
// ShardID, but in the order that OnCandidate was called.
std::vector<EvictionCandidateList> candidates_per_shard_ GUARDED_BY(lock_);
// Callbacks to run on each shard after the eviction candidates have been
// selected. This is ordered by ShardId.
std::vector<EvictionCandidateSelectedCallback> selected_callbacks_
GUARDED_BY(lock_);
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace disk_cache
#endif // NET_DISK_CACHE_SQL_EVICTION_CANDIDATE_AGGREGATOR_H_
|