#ifndef GPU_IPC_HOST_GPU_DISK_CACHE_H_
#define GPU_IPC_HOST_GPU_DISK_CACHE_H_
#include <stdint.h>
#include <string>
#include <unordered_map>
#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/files/file_path.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "gpu/ipc/common/gpu_disk_cache_type.h"
#include "net/base/completion_once_callback.h"
#include "net/disk_cache/disk_cache.h"
namespace gpu {
class GpuDiskCacheFactory;
class GpuDiskCacheEntry;
class GpuDiskCacheReadHelper;
class GpuDiskCacheClearHelper;
class GpuDiskCache : public base::RefCounted<GpuDiskCache> {
public:
using BlobLoadedCallback =
base::RepeatingCallback<void(const std::string&, const std::string&)>;
GpuDiskCache(const GpuDiskCache&) = delete;
GpuDiskCache& operator=(const GpuDiskCache&) = delete;
void Cache(const std::string& key, const std::string& blob);
int Clear(base::Time begin_time,
base::Time end_time,
net::CompletionOnceCallback completion_callback);
int SetAvailableCallback(net::CompletionOnceCallback callback);
int32_t Size(net::CompletionOnceCallback callback);
int SetCacheCompleteCallback(net::CompletionOnceCallback callback);
private:
friend class base::RefCounted<GpuDiskCache>;
friend class GpuDiskCacheEntry;
friend class GpuDiskCacheReadHelper;
friend class GpuDiskCacheFactory;
GpuDiskCache(GpuDiskCacheFactory* factory,
const base::FilePath& cache_path,
const BlobLoadedCallback& blob_loaded_cb,
base::OnceClosure cache_destroyed_cb);
~GpuDiskCache();
void Init();
void CacheCreatedCallback(disk_cache::BackendResult rv);
disk_cache::Backend* backend() { return backend_.get(); }
void EntryComplete(GpuDiskCacheEntry* entry);
void ReadComplete();
raw_ptr<GpuDiskCacheFactory> factory_;
bool cache_available_ = false;
base::FilePath cache_path_;
bool is_initialized_ = false;
net::CompletionOnceCallback available_callback_;
net::CompletionOnceCallback cache_complete_callback_;
BlobLoadedCallback blob_loaded_cb_;
base::OnceClosure cache_destroyed_cb_;
std::unique_ptr<disk_cache::Backend> backend_;
std::unique_ptr<GpuDiskCacheReadHelper> helper_;
std::unordered_map<GpuDiskCacheEntry*, std::unique_ptr<GpuDiskCacheEntry>>
entries_;
};
class GpuDiskCacheFactory {
public:
using HandleToPathMap = base::flat_map<GpuDiskCacheHandle, base::FilePath>;
using BlobLoadedForCacheCallback = base::RepeatingCallback<
void(const GpuDiskCacheHandle&, const std::string&, const std::string&)>;
using CacheDestroyedCallback =
base::OnceCallback<void(const GpuDiskCacheHandle&)>;
explicit GpuDiskCacheFactory(
const HandleToPathMap& reserved_handles = HandleToPathMap());
GpuDiskCacheFactory(const GpuDiskCacheFactory&) = delete;
GpuDiskCacheFactory& operator=(const GpuDiskCacheFactory&) = delete;
virtual ~GpuDiskCacheFactory();
void ClearByCache(scoped_refptr<GpuDiskCache> cache,
base::Time begin_time,
base::Time end_time,
base::OnceClosure callback);
virtual void ClearByPath(const base::FilePath& path,
base::Time begin_time,
base::Time end_time,
base::OnceClosure callback);
GpuDiskCacheHandle GetCacheHandle(GpuDiskCacheType type,
const base::FilePath& path);
void ReleaseCacheHandle(GpuDiskCache* cache);
scoped_refptr<GpuDiskCache> Get(const GpuDiskCacheHandle& handle);
scoped_refptr<GpuDiskCache> Create(
const GpuDiskCacheHandle& handle,
const BlobLoadedForCacheCallback& blob_loaded_cb = base::DoNothing(),
CacheDestroyedCallback cache_destroyed_cb = base::DoNothing());
void AddToCache(const base::FilePath& path, GpuDiskCache* cache);
void RemoveFromCache(const base::FilePath& path);
private:
friend class GpuDiskCacheClearHelper;
scoped_refptr<GpuDiskCache> GetOrCreateByPath(
const base::FilePath& path,
const GpuDiskCache::BlobLoadedCallback& blob_loaded_cb =
base::DoNothing(),
base::OnceClosure cache_destroyed_cb = base::DoNothing());
void CacheCleared(GpuDiskCache* cache);
THREAD_CHECKER(thread_checker_);
HandleToPathMap handle_to_path_map_;
using PathToHandleMap =
base::flat_map<base::FilePath, gpu::GpuDiskCacheHandle>;
PathToHandleMap path_to_handle_map_;
using HandleRefCounts = base::flat_map<GpuDiskCacheHandle, uint32_t>;
HandleRefCounts handle_ref_counts_;
using PathToCacheMap =
base::flat_map<base::FilePath, raw_ptr<GpuDiskCache, CtnExperimental>>;
PathToCacheMap gpu_cache_map_;
using ClearHelperQueue =
base::queue<std::unique_ptr<GpuDiskCacheClearHelper>>;
using CacheToClearHelperQueueMap =
base::flat_map<GpuDiskCache*, ClearHelperQueue>;
CacheToClearHelperQueueMap gpu_clear_map_;
int32_t next_available_handle_ = 0;
};
}
#endif