diff options
author | Sanjay Ghemawat <sanjay@google.com> | 2012-03-15 09:14:00 -0700 |
---|---|---|
committer | Sanjay Ghemawat <sanjay@google.com> | 2012-03-15 09:14:00 -0700 |
commit | 9013f13b1512f6ab8c04518e8f036e58be271eba (patch) | |
tree | e5c2bed9104f74183981e1ff254074b362f6a856 /util/env_posix.cc | |
parent | 583f1499c00ff40f332149021f583cf6ee78dd7e (diff) | |
download | leveldb-9013f13b1512f6ab8c04518e8f036e58be271eba.tar.gz |
use mmap on 64-bit machines to speed-up reads; small build fixes
Diffstat (limited to 'util/env_posix.cc')
-rw-r--r-- | util/env_posix.cc | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/util/env_posix.cc b/util/env_posix.cc index cc73348..cb1f6fc 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -66,6 +66,7 @@ class PosixSequentialFile: public SequentialFile { } }; +// pread() based random-access class PosixRandomAccessFile: public RandomAccessFile { private: std::string filename_; @@ -89,6 +90,32 @@ class PosixRandomAccessFile: public RandomAccessFile { } }; +// mmap() based random-access +class PosixMmapReadableFile: public RandomAccessFile { + private: + 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) + : filename_(fname), mmapped_region_(base), length_(length) { } + virtual ~PosixMmapReadableFile() { munmap(mmapped_region_, length_); } + + virtual Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const { + Status s; + if (offset + n > length_) { + *result = Slice(); + s = IOError(filename_, EINVAL); + } else { + *result = Slice(reinterpret_cast<char*>(mmapped_region_) + offset, n); + } + return s; + } +}; + // We preallocate up to an extra megabyte and use memcpy to append new // data to the file. This is safe since we either properly close the // file before reading from it, or for log files, the reading code @@ -297,13 +324,28 @@ class PosixEnv : public Env { virtual Status NewRandomAccessFile(const std::string& fname, RandomAccessFile** result) { + *result = NULL; + Status s; int fd = open(fname.c_str(), O_RDONLY); if (fd < 0) { - *result = NULL; - return IOError(fname, errno); + s = IOError(fname, errno); + } else if (sizeof(void*) >= 8) { + // Use mmap when virtual address-space is plentiful. + uint64_t size; + s = GetFileSize(fname, &size); + if (s.ok()) { + void* base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (base != MAP_FAILED) { + *result = new PosixMmapReadableFile(fname, base, size); + } else { + s = IOError(fname, errno); + } + } + close(fd); + } else { + *result = new PosixRandomAccessFile(fname, fd); } - *result = new PosixRandomAccessFile(fname, fd); - return Status::OK(); + return s; } virtual Status NewWritableFile(const std::string& fname, |