diff --git a/db/db_bench.cc b/db/db_bench.cc index 4232803378..0d364c6f67 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -170,6 +170,7 @@ static leveldb::Env* FLAGS_env = leveldb::Env::Default(); extern bool useOsBuffer; extern bool useFsReadAhead; +extern bool useMmapRead; namespace leveldb { @@ -1182,6 +1183,9 @@ int main(int argc, char** argv) { } else if (sscanf(argv[i], "--bufferedio=%d%c", &n, &junk) == 1 && (n == 0 || n == 1)) { useOsBuffer = n; + } else if (sscanf(argv[i], "--mmap_read=%d%c", &n, &junk) == 1 && + (n == 0 || n == 1)) { + useMmapRead = n; } else if (sscanf(argv[i], "--readhead=%d%c", &n, &junk) == 1 && (n == 0 || n == 1)) { useFsReadAhead = n; diff --git a/util/env_posix.cc b/util/env_posix.cc index 63ee25b850..75c953c741 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -28,6 +28,7 @@ bool useOsBuffer = 1; // cache data in OS buffers bool useFsReadAhead = 1; // allow filesystem to do readaheads +bool useMmapRead = 0; namespace leveldb { @@ -386,13 +387,26 @@ class PosixEnv : public Env { virtual Status NewRandomAccessFile(const std::string& fname, RandomAccessFile** result) { - // Use of mmap for random reads has been removed because it - // kills performance when storage is fast. *result = NULL; Status s; int fd = open(fname.c_str(), O_RDONLY); if (fd < 0) { s = IOError(fname, errno); + } else if (useMmapRead && sizeof(void*) >= 8) { + // Use of mmap for random reads has been removed because it + // kills performance when storage is fast. + // 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); }