diff options
author | Patrick Strateman <patrick.strateman@gmail.com> | 2013-12-01 23:01:16 -0600 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-12-05 13:10:24 +0100 |
commit | 5f553f8422667f956c6a750a0febcd262f37c506 (patch) | |
tree | e62e5ded8b2fbef3c35dde1922853975a7c6ed78 | |
parent | 1eb11e32e82deec9a85b77b3969684739f4a5d4e (diff) |
dont use mmap in leveldb, this is a marginal performance hit
fail on short writes
Ensure new files referred to by the manifest are in the filesystem.
-rw-r--r-- | src/leveldb/util/env_posix.cc | 102 |
1 files changed, 86 insertions, 16 deletions
diff --git a/src/leveldb/util/env_posix.cc b/src/leveldb/util/env_posix.cc index 0f5dcfac5a..9859e25c4b 100644 --- a/src/leveldb/util/env_posix.cc +++ b/src/leveldb/util/env_posix.cc @@ -377,6 +377,91 @@ class PosixMmapFile : public WritableFile { } }; +class PosixWriteableFile : public WritableFile { + private: + std::string filename_; + int fd_; + public: + PosixWriteableFile(const std::string& fname, int fd) + : filename_(fname), + fd_(fd) + { } + + + ~PosixWriteableFile() { + if (fd_ >= 0) { + PosixWriteableFile::Close(); + } + } + + virtual Status Append(const Slice& data) { + Status s; + int ret; + ret = write(fd_, data.data(), data.size()); + if (ret < 0) { + s = IOError(filename_, errno); + } else if (ret < data.size()) { + s = Status::IOError(filename_, "short write"); + } + + return s; + } + + virtual Status Close() { + Status s; + if (close(fd_) < 0) { + s = IOError(filename_, errno); + } + fd_ = -1; + return s; + } + + virtual Status Flush() { + return Status::OK(); + } + + Status SyncDirIfManifest() { + const char* f = filename_.c_str(); + const char* sep = strrchr(f, '/'); + Slice basename; + std::string dir; + if (sep == NULL) { + dir = "."; + basename = f; + } else { + dir = std::string(f, sep - f); + basename = sep + 1; + } + Status s; + if (basename.starts_with("MANIFEST")) { + int fd = open(dir.c_str(), O_RDONLY); + if (fd < 0) { + s = IOError(dir, errno); + } else { + if (fsync(fd) < 0) { + s = IOError(dir, errno); + } + close(fd); + } + } + return s; + } + + virtual Status Sync() { + // Ensure new files referred to by the manifest are in the filesystem. + Status s = SyncDirIfManifest(); + if (!s.ok()) { + return s; + } + + if (fdatasync(fd_) < 0) { + s = IOError(filename_, errno); + } + + return s; + } +}; + static int LockOrUnlock(int fd, bool lock) { errno = 0; struct flock f; @@ -439,21 +524,6 @@ class PosixEnv : public Env { int fd = open(fname.c_str(), O_RDONLY); if (fd < 0) { s = IOError(fname, errno); - } else if (mmap_limit_.Acquire()) { - 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, &mmap_limit_); - } else { - s = IOError(fname, errno); - } - } - close(fd); - if (!s.ok()) { - mmap_limit_.Release(); - } } else { *result = new PosixRandomAccessFile(fname, fd); } @@ -468,7 +538,7 @@ class PosixEnv : public Env { *result = NULL; s = IOError(fname, errno); } else { - *result = new PosixMmapFile(fname, fd, page_size_); + *result = new PosixWriteableFile(fname, fd); } return s; } |