class RateLimiter;
class ThreadStatusUpdater;
struct ThreadStatus;
+class FileSystem;
const size_t kDefaultPageSize = 4 * 1024;
+enum class CpuPriority {
+ kIdle = 0,
+ kLow = 1,
+ kNormal = 2,
+ kHigh = 3,
+};
+
// Options while opening a file to read/write
struct EnvOptions {
// Construct with default Options
uint64_t size_bytes;
};
- Env() : thread_status_updater_(nullptr) {}
+ Env();
+ // Construct an Env with a separate FileSystem implementation
+ Env(std::shared_ptr<FileSystem> fs);
// No copying allowed
Env(const Env&) = delete;
void operator=(const Env&) = delete;
// The result of Default() belongs to rocksdb and must never be deleted.
static Env* Default();
+ // See FileSystem::RegisterDbPaths.
+ virtual Status RegisterDbPaths(const std::vector<std::string>& /*paths*/) {
+ return Status::OK();
+ }
+ // See FileSystem::UnregisterDbPaths.
+ virtual Status UnregisterDbPaths(const std::vector<std::string>& /*paths*/) {
+ return Status::OK();
+ }
+
// Create a brand new sequentially-readable file with the specified name.
// On success, stores a pointer to the new file in *result and returns OK.
// On failure stores nullptr in *result and returns non-OK. If the file does
virtual Status ReopenWritableFile(const std::string& /*fname*/,
std::unique_ptr<WritableFile>* /*result*/,
const EnvOptions& /*options*/) {
- return Status::NotSupported();
+ return Status::NotSupported("Env::ReopenWritableFile() not supported.");
}
// Reuse an existing file by renaming it and opening it as writable.
virtual Status CreateDirIfMissing(const std::string& dirname) = 0;
// Delete the specified directory.
+ // Many implementations of this function will only delete a directory if it is
+ // empty.
virtual Status DeleteDir(const std::string& dirname) = 0;
// Store the size of fname in *file_size.
// Sleep/delay the thread for the prescribed number of micro-seconds.
virtual void SleepForMicroseconds(int micros) = 0;
- // Get the current host name.
+ // Get the current host name as a null terminated string iff the string
+ // length is < len. The hostname should otherwise be truncated to len.
virtual Status GetHostName(char* name, uint64_t len) = 0;
+ // Get the current hostname from the given env as a std::string in result.
+ // The result may be truncated if the hostname is too
+ // long
+ virtual Status GetHostNameString(std::string* result);
+
// Get the number of seconds since the Epoch, 1970-01-01 00:00:00 (UTC).
// Only overwrites *unix_time on success.
virtual Status GetCurrentTime(int64_t* unix_time) = 0;
virtual int GetBackgroundThreads(Priority pri = LOW) = 0;
virtual Status SetAllowNonOwnerAccess(bool /*allow_non_owner_access*/) {
- return Status::NotSupported("Not supported.");
+ return Status::NotSupported("Env::SetAllowNonOwnerAccess() not supported.");
}
// Enlarge number of background worker threads of a specific thread pool
// Lower IO priority for threads from the specified pool.
virtual void LowerThreadPoolIOPriority(Priority /*pool*/ = LOW) {}
+ // Lower CPU priority for threads from the specified pool.
+ virtual Status LowerThreadPoolCPUPriority(Priority /*pool*/,
+ CpuPriority /*pri*/) {
+ return Status::NotSupported(
+ "Env::LowerThreadPoolCPUPriority(Priority, CpuPriority) not supported");
+ }
+
// Lower CPU priority for threads from the specified pool.
virtual void LowerThreadPoolCPUPriority(Priority /*pool*/ = LOW) {}
// Returns the status of all threads that belong to the current Env.
virtual Status GetThreadList(std::vector<ThreadStatus>* /*thread_list*/) {
- return Status::NotSupported("Not supported.");
+ return Status::NotSupported("Env::GetThreadList() not supported.");
}
// Returns the pointer to ThreadStatusUpdater. This function will be
// Get the amount of free disk space
virtual Status GetFreeSpace(const std::string& /*path*/,
uint64_t* /*diskfree*/) {
- return Status::NotSupported();
+ return Status::NotSupported("Env::GetFreeSpace() not supported.");
+ }
+
+ // Check whether the specified path is a directory
+ virtual Status IsDirectory(const std::string& /*path*/, bool* /*is_dir*/) {
+ return Status::NotSupported("Env::IsDirectory() not supported.");
}
virtual void SanitizeEnvOptions(EnvOptions* /*env_opts*/) const {}
+ // Get the FileSystem implementation this Env was constructed with. It
+ // could be a fully implemented one, or a wrapper class around the Env
+ const std::shared_ptr<FileSystem>& GetFileSystem() const;
+
// If you're adding methods here, remember to add them to EnvWrapper too.
protected:
// The pointer to an internal structure that will update the
// status of each thread.
ThreadStatusUpdater* thread_status_updater_;
+
+ // Pointer to the underlying FileSystem implementation
+ std::shared_ptr<FileSystem> file_system_;
+
+ private:
+ static const size_t kMaxHostNameLen = 256;
};
// The factory function to construct a ThreadStatusUpdater. Any Env
// of this file. If the length is 0, then it refers to the end of file.
// If the system is not caching the file contents, then this is a noop.
virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
- return Status::NotSupported("InvalidateCache not supported.");
+ return Status::NotSupported(
+ "SequentialFile::InvalidateCache not supported.");
}
// Positioned Read for direct I/O
// If Direct I/O enabled, offset, n, and scratch should be properly aligned
virtual Status PositionedRead(uint64_t /*offset*/, size_t /*n*/,
Slice* /*result*/, char* /*scratch*/) {
- return Status::NotSupported();
+ return Status::NotSupported(
+ "SequentialFile::PositionedRead() not supported.");
}
// If you're adding methods here, remember to add them to
// of this file. If the length is 0, then it refers to the end of file.
// If the system is not caching the file contents, then this is a noop.
virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
- return Status::NotSupported("InvalidateCache not supported.");
+ return Status::NotSupported(
+ "RandomAccessFile::InvalidateCache not supported.");
}
// If you're adding methods here, remember to add them to
// required is queried via GetRequiredBufferAlignment()
virtual Status PositionedAppend(const Slice& /* data */,
uint64_t /* offset */) {
- return Status::NotSupported();
+ return Status::NotSupported(
+ "WritableFile::PositionedAppend() not supported.");
}
// Truncate is necessary to trim the file to the correct size
// If the system is not caching the file contents, then this is a noop.
// This call has no effect on dirty pages in the cache.
virtual Status InvalidateCache(size_t /*offset*/, size_t /*length*/) {
- return Status::NotSupported("InvalidateCache not supported.");
+ return Status::NotSupported("WritableFile::InvalidateCache not supported.");
}
// Sync a file range with disk.
if (new_last_preallocated_block > last_preallocated_block_) {
size_t num_spanned_blocks =
new_last_preallocated_block - last_preallocated_block_;
+ // TODO: Don't ignore errors from allocate
Allocate(block_size * last_preallocated_block_,
- block_size * num_spanned_blocks);
+ block_size * num_spanned_blocks)
+ .PermitUncheckedError();
last_preallocated_block_ = new_last_preallocated_block;
}
}
virtual void LogHeader(const char* format, va_list ap) {
// Default implementation does a simple INFO level log write.
// Please override as per the logger class requirement.
- Logv(format, ap);
+ Logv(InfoLogLevel::INFO_LEVEL, format, ap);
}
// Write an entry to the log file with the specified format.
- virtual void Logv(const char* format, va_list ap) = 0;
+ //
+ // Users who override the `Logv()` overload taking `InfoLogLevel` do not need
+ // to implement this, unless they explicitly invoke it in
+ // `Logv(InfoLogLevel, ...)`.
+ virtual void Logv(const char* /* format */, va_list /* ap */) {
+ assert(false);
+ }
// Write an entry to the log file with the specified log level
// and format. Any log with level under the internal log level
Env* target() const { return target_; }
// The following text is boilerplate that forwards all methods to target()
+ Status RegisterDbPaths(const std::vector<std::string>& paths) override {
+ return target_->RegisterDbPaths(paths);
+ }
+
+ Status UnregisterDbPaths(const std::vector<std::string>& paths) override {
+ return target_->UnregisterDbPaths(paths);
+ }
+
Status NewSequentialFile(const std::string& f,
std::unique_ptr<SequentialFile>* r,
const EnvOptions& options) override {
Status UnlockFile(FileLock* l) override { return target_->UnlockFile(l); }
+ Status IsDirectory(const std::string& path, bool* is_dir) override {
+ return target_->IsDirectory(path, is_dir);
+ }
+
Status LoadLibrary(const std::string& lib_name,
const std::string& search_path,
std::shared_ptr<DynamicLibrary>* result) override {
return target_->IncBackgroundThreadsIfNeeded(num, pri);
}
- void LowerThreadPoolIOPriority(Priority pool = LOW) override {
+ void LowerThreadPoolIOPriority(Priority pool) override {
target_->LowerThreadPoolIOPriority(pool);
}
- void LowerThreadPoolCPUPriority(Priority pool = LOW) override {
+ void LowerThreadPoolCPUPriority(Priority pool) override {
target_->LowerThreadPoolCPUPriority(pool);
}
+ Status LowerThreadPoolCPUPriority(Priority pool, CpuPriority pri) override {
+ return target_->LowerThreadPoolCPUPriority(pool, pri);
+ }
+
std::string TimeToString(uint64_t time) override {
return target_->TimeToString(time);
}
Status NewEnvLogger(const std::string& fname, Env* env,
std::shared_ptr<Logger>* result);
+std::unique_ptr<Env> NewCompositeEnv(std::shared_ptr<FileSystem> fs);
+
} // namespace ROCKSDB_NAMESPACE