Files
doris/be/src/util/file_cache.h
sduzh 6fedf5881b [CodeFormat] Clang-format cpp sources (#4965)
Clang-format all c++ source files.
2020-11-28 18:36:49 +08:00

152 lines
5.1 KiB
C++

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <string>
#include "olap/lru_cache.h"
namespace doris {
class Env;
// A "smart" retrieved LRU cache handle.
//
// The cache handle is released when this object goes out of scope, possibly
// closing the opened file if it is no longer in the cache.
template <class FileType>
class OpenedFileHandle {
public:
OpenedFileHandle() : _cache(nullptr), _handle(nullptr) {}
// A opened file handle
explicit OpenedFileHandle(Cache* cache, Cache::Handle* handle)
: _cache(cache), _handle(handle) {}
// release cache handle
~OpenedFileHandle() {
if (_handle != nullptr) {
_cache->release(_handle);
}
}
OpenedFileHandle(OpenedFileHandle&& other) noexcept {
std::swap(_cache, other._cache);
std::swap(_handle, other._handle);
}
OpenedFileHandle& operator=(OpenedFileHandle&& other) noexcept {
std::swap(_cache, other._cache);
std::swap(_handle, other._handle);
return *this;
}
FileType* file() const {
DCHECK(_handle != nullptr);
return reinterpret_cast<FileType*>(_cache->value(_handle));
}
private:
Cache* _cache;
Cache::Handle* _handle;
};
// Cache of open files.
//
// The purpose of this cache is to enforce an upper bound on the maximum number
// of files open at a time. Files opened through the cache may be closed at any
// time, only to be reopened upon next use.
//
// The file cache can be viewed as having two logical parts: the client-facing
// File handle and the LRU cache.
//
// Client-facing API
// -----------------
// The core of the client-facing API is the cache descriptor. A descriptor
// LRU cache
// ---------
// The lower half of the file cache is a standard LRU cache whose keys are file
// names and whose values are pointers to opened file objects allocated on the
// heap. Unlike the descriptor map, this cache has an upper bound on capacity,
// and handles are evicted (and closed) according to an LRU algorithm.
//
// Whenever a descriptor is used by a client in file I/O, its file name is used
// in an LRU cache lookup. If found, the underlying file is still open and the
// file access is performed. Otherwise, the file must have been evicted and
// closed, so it is reopened and reinserted (possibly evicting a different open
// file) before the file access is performed.
//
// Every public method in the file cache is thread safe.
template <class FileType>
class FileCache {
public:
// Creates a new file cache.
//
// The 'cache_name' is used to disambiguate amongst other file cache
// instances. The cache will use 'max_open_files' as a soft upper bound on
// the number of files open at any given time.
// for this constructor, _is_cache_own is set to true, indicating that _cache
// is only owned by this.
FileCache(const std::string& cache_name, int max_open_files);
// Creates a new file cache with given cache.
//
// The 'cache_name' is used to disambiguate amongst other file cache
// instances. Please use this constructor only you want to share _cache
// with other.
// for this constructor, _is_cache_own is set to false, indicating that _cache
// is sharing with other (In most case, sharing _cache with storage engine).
FileCache(const std::string& cache_name, std::shared_ptr<Cache> cache);
// Destroys the file cache.
~FileCache() {
// If _cache is only owned by this, reset the shared_ptr of _cache.
if (_is_cache_own) {
_cache.reset();
}
}
// find whether the file has been cached
// if cached, return true and set the file_handle
// else return false
bool lookup(const std::string& file_name, OpenedFileHandle<FileType>* file_handle);
// insert new FileType* into lru cache
// and return file_handle
void insert(const std::string& file_name, FileType* file,
OpenedFileHandle<FileType>* file_handle);
private:
// Name of the cache.
std::string _cache_name;
// Underlying cache instance. Caches opened files.
std::shared_ptr<Cache> _cache;
// Indicates weather _cache is only owned by this,
// generally, _cache can be shared by other, in
// this case, _is_cache_own is set to false.
bool _is_cache_own = false;
DISALLOW_COPY_AND_ASSIGN(FileCache);
};
} // namespace doris