mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Implement apis in the Environment to clear out pages in the OS cache.
Summary: Added a new api to the Environment that allows clearing out not-needed pages from the OS cache. This will be helpful when the compressed block cache replaces the OS cache. Test Plan: EnvPosixTest.InvalidateCache Reviewers: haobo Reviewed By: haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D13041
This commit is contained in:
@@ -137,6 +137,15 @@ class PosixSequentialFile: public SequentialFile {
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
virtual Status InvalidateCache(size_t offset, size_t length) {
|
||||
// free OS pages
|
||||
int ret = posix_fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
|
||||
if (ret == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
return IOError(filename_, errno);
|
||||
}
|
||||
};
|
||||
|
||||
// pread() based random-access
|
||||
@@ -223,20 +232,30 @@ class PosixRandomAccessFile: public RandomAccessFile {
|
||||
}
|
||||
}
|
||||
|
||||
virtual Status InvalidateCache(size_t offset, size_t length) {
|
||||
// free OS pages
|
||||
int ret = posix_fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
|
||||
if (ret == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
return IOError(filename_, errno);
|
||||
}
|
||||
};
|
||||
|
||||
// mmap() based random-access
|
||||
class PosixMmapReadableFile: public RandomAccessFile {
|
||||
private:
|
||||
int fd_;
|
||||
std::string filename_;
|
||||
void* mmapped_region_;
|
||||
size_t length_;
|
||||
|
||||
public:
|
||||
// base[0,length-1] contains the mmapped contents of the file.
|
||||
PosixMmapReadableFile(const std::string& fname, void* base, size_t length,
|
||||
PosixMmapReadableFile(const int fd, const std::string& fname,
|
||||
void* base, size_t length,
|
||||
const EnvOptions& options)
|
||||
: filename_(fname), mmapped_region_(base), length_(length) {
|
||||
: fd_(fd), filename_(fname), mmapped_region_(base), length_(length) {
|
||||
assert(options.use_mmap_reads);
|
||||
assert(options.use_os_buffer);
|
||||
}
|
||||
@@ -253,6 +272,14 @@ class PosixMmapReadableFile: public RandomAccessFile {
|
||||
}
|
||||
return s;
|
||||
}
|
||||
virtual Status InvalidateCache(size_t offset, size_t length) {
|
||||
// free OS pages
|
||||
int ret = posix_fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
|
||||
if (ret == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
return IOError(filename_, errno);
|
||||
}
|
||||
};
|
||||
|
||||
// We preallocate up to an extra megabyte and use memcpy to append new
|
||||
@@ -480,6 +507,15 @@ class PosixMmapFile : public WritableFile {
|
||||
return file_offset_ + used;
|
||||
}
|
||||
|
||||
virtual Status InvalidateCache(size_t offset, size_t length) {
|
||||
// free OS pages
|
||||
int ret = posix_fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
|
||||
if (ret == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
return IOError(filename_, errno);
|
||||
}
|
||||
|
||||
#ifdef OS_LINUX
|
||||
virtual Status Allocate(off_t offset, off_t len) {
|
||||
TEST_KILL_RANDOM(leveldb_kill_odds);
|
||||
@@ -644,6 +680,15 @@ class PosixWritableFile : public WritableFile {
|
||||
return filesize_;
|
||||
}
|
||||
|
||||
virtual Status InvalidateCache(size_t offset, size_t length) {
|
||||
// free OS pages
|
||||
int ret = posix_fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
|
||||
if (ret == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
return IOError(filename_, errno);
|
||||
}
|
||||
|
||||
#ifdef OS_LINUX
|
||||
virtual Status Allocate(off_t offset, off_t len) {
|
||||
TEST_KILL_RANDOM(leveldb_kill_odds);
|
||||
@@ -768,7 +813,8 @@ class PosixEnv : public Env {
|
||||
if (s.ok()) {
|
||||
void* base = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (base != MAP_FAILED) {
|
||||
result->reset(new PosixMmapReadableFile(fname, base, size, options));
|
||||
result->reset(new PosixMmapReadableFile(fd, fname, base,
|
||||
size, options));
|
||||
} else {
|
||||
s = IOError(fname, errno);
|
||||
}
|
||||
|
||||
@@ -317,6 +317,46 @@ TEST(EnvPosixTest, RandomAccessUniqueIDDeletes) {
|
||||
ASSERT_TRUE(!HasPrefix(ids));
|
||||
}
|
||||
|
||||
TEST(EnvPosixTest, InvalidateCache) {
|
||||
const EnvOptions soptions;
|
||||
std::string fname = test::TmpDir() + "/" + "testfile";
|
||||
|
||||
// Create file.
|
||||
{
|
||||
unique_ptr<WritableFile> wfile;
|
||||
ASSERT_OK(env_->NewWritableFile(fname, &wfile, soptions));
|
||||
ASSERT_OK(wfile.get()->Append(Slice("Hello world")));
|
||||
ASSERT_OK(wfile.get()->InvalidateCache(0, 0));
|
||||
ASSERT_OK(wfile.get()->Close());
|
||||
}
|
||||
|
||||
// Random Read
|
||||
{
|
||||
unique_ptr<RandomAccessFile> file;
|
||||
char scratch[100];
|
||||
Slice result;
|
||||
ASSERT_OK(env_->NewRandomAccessFile(fname, &file, soptions));
|
||||
ASSERT_OK(file.get()->Read(0, 11, &result, scratch));
|
||||
ASSERT_EQ(memcmp(scratch, "Hello world", 11), 0);
|
||||
ASSERT_OK(file.get()->InvalidateCache(0, 11));
|
||||
ASSERT_OK(file.get()->InvalidateCache(0, 0));
|
||||
}
|
||||
|
||||
// Sequential Read
|
||||
{
|
||||
unique_ptr<SequentialFile> file;
|
||||
char scratch[100];
|
||||
Slice result;
|
||||
ASSERT_OK(env_->NewSequentialFile(fname, &file, soptions));
|
||||
ASSERT_OK(file.get()->Read(11, &result, scratch));
|
||||
ASSERT_EQ(memcmp(scratch, "Hello world", 11), 0);
|
||||
ASSERT_OK(file.get()->InvalidateCache(0, 11));
|
||||
ASSERT_OK(file.get()->InvalidateCache(0, 0));
|
||||
}
|
||||
// Delete the file
|
||||
ASSERT_OK(env_->DeleteFile(fname));
|
||||
}
|
||||
|
||||
} // namespace leveldb
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
Reference in New Issue
Block a user