// multiple threads without any external synchronization.
#pragma once
-
-#include "port/win/win_thread.h"
-#include <rocksdb/env.h>
-#include "util/threadpool_imp.h"
-
#include <stdint.h>
#include <windows.h>
#include <mutex>
-#include <vector>
#include <string>
+#include <vector>
+#include "env/composite_env_wrapper.h"
+#include "port/port.h"
+#include "rocksdb/env.h"
+#include "rocksdb/file_system.h"
+#include "rocksdb/system_clock.h"
+#include "util/threadpool_imp.h"
#undef GetCurrentTime
#undef DeleteFile
-#undef GetTickCount
+#undef LoadLibrary
namespace ROCKSDB_NAMESPACE {
namespace port {
// Currently not designed for inheritance but rather a replacement
class WinEnvThreads {
-public:
-
+ public:
explicit WinEnvThreads(Env* hosted_env);
~WinEnvThreads();
WinEnvThreads(const WinEnvThreads&) = delete;
WinEnvThreads& operator=(const WinEnvThreads&) = delete;
- void Schedule(void(*function)(void*), void* arg, Env::Priority pri,
- void* tag, void(*unschedFunction)(void* arg));
+ void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
+ void* tag, void (*unschedFunction)(void* arg));
int UnSchedule(void* arg, Env::Priority pri);
- void StartThread(void(*function)(void* arg), void* arg);
+ void StartThread(void (*function)(void* arg), void* arg);
void WaitForJoin();
unsigned int GetThreadPoolQueueLen(Env::Priority pri) const;
+ int ReserveThreads(int threads_to_be_reserved, Env::Priority pri);
+
+ int ReleaseThreads(int threads_to_be_released, Env::Priority pri);
+
static uint64_t gettid();
uint64_t GetThreadID() const;
- void SleepForMicroseconds(int micros);
-
// Allow increasing the number of worker threads.
void SetBackgroundThreads(int num, Env::Priority pri);
int GetBackgroundThreads(Env::Priority pri);
void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri);
-private:
-
+ private:
Env* hosted_env_;
mutable std::mutex mu_;
std::vector<ThreadPoolImpl> thread_pools_;
- std::vector<WindowsThread> threads_to_join_;
-
+ std::vector<Thread> threads_to_join_;
};
-// Designed for inheritance so can be re-used
-// but certain parts replaced
-class WinEnvIO {
-public:
- explicit WinEnvIO(Env* hosted_env);
-
- virtual ~WinEnvIO();
-
- virtual Status DeleteFile(const std::string& fname);
-
- Status Truncate(const std::string& fname, size_t size);
-
- virtual Status GetCurrentTime(int64_t* unix_time);
-
- virtual Status NewSequentialFile(const std::string& fname,
- std::unique_ptr<SequentialFile>* result,
- const EnvOptions& options);
-
- // Helper for NewWritable and ReopenWritableFile
- virtual Status OpenWritableFile(const std::string& fname,
- std::unique_ptr<WritableFile>* result,
- const EnvOptions& options,
- bool reopen);
-
- virtual Status NewRandomAccessFile(const std::string& fname,
- std::unique_ptr<RandomAccessFile>* result,
- const EnvOptions& options);
-
- // The returned file will only be accessed by one thread at a time.
- virtual Status NewRandomRWFile(const std::string& fname,
- std::unique_ptr<RandomRWFile>* result,
- const EnvOptions& options);
-
- virtual Status NewMemoryMappedFileBuffer(
- const std::string& fname,
- std::unique_ptr<MemoryMappedFileBuffer>* result);
-
- virtual Status NewDirectory(const std::string& name,
- std::unique_ptr<Directory>* result);
-
- virtual Status FileExists(const std::string& fname);
-
- virtual Status GetChildren(const std::string& dir,
- std::vector<std::string>* result);
+class WinClock : public SystemClock {
+ public:
+ WinClock();
+ virtual ~WinClock() {}
- virtual Status CreateDir(const std::string& name);
+ static const char* kClassName() { return "WindowsClock"; }
+ const char* Name() const override { return kDefaultName(); }
+ const char* NickName() const override { return kClassName(); }
- virtual Status CreateDirIfMissing(const std::string& name);
-
- virtual Status DeleteDir(const std::string& name);
-
- virtual Status GetFileSize(const std::string& fname, uint64_t* size);
-
- static uint64_t FileTimeToUnixTime(const FILETIME& ftTime);
-
- virtual Status GetFileModificationTime(const std::string& fname,
- uint64_t* file_mtime);
-
- virtual Status RenameFile(const std::string& src, const std::string& target);
-
- virtual Status LinkFile(const std::string& src, const std::string& target);
-
- virtual Status NumFileLinks(const std::string& /*fname*/,
- uint64_t* /*count*/);
-
- virtual Status AreFilesSame(const std::string& first,
- const std::string& second, bool* res);
-
- virtual Status LockFile(const std::string& lockFname, FileLock** lock);
-
- virtual Status UnlockFile(FileLock* lock);
-
- virtual Status GetTestDirectory(std::string* result);
-
- virtual Status NewLogger(const std::string& fname,
- std::shared_ptr<Logger>* result);
-
- virtual Status IsDirectory(const std::string& path, bool* is_dir);
-
- virtual uint64_t NowMicros();
-
- virtual uint64_t NowNanos();
-
- virtual Status GetHostName(char* name, uint64_t len);
-
- virtual Status GetAbsolutePath(const std::string& db_path,
- std::string* output_path);
-
- // This seems to clash with a macro on Windows, so #undef it here
-#undef GetFreeSpace
-
- // Get the amount of free disk space
- virtual Status GetFreeSpace(const std::string& path, uint64_t* diskfree);
-
- virtual std::string TimeToString(uint64_t secondsSince1970);
-
- virtual EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
- const DBOptions& db_options) const;
-
- virtual EnvOptions OptimizeForManifestWrite(
- const EnvOptions& env_options) const;
+ uint64_t NowMicros() override;
- virtual EnvOptions OptimizeForManifestRead(
- const EnvOptions& env_options) const;
+ uint64_t NowNanos() override;
- size_t GetPageSize() const { return page_size_; }
+ // 0 indicates not supported
+ uint64_t CPUMicros() override { return 0; }
+ void SleepForMicroseconds(int micros) override;
- size_t GetAllocationGranularity() const { return allocation_granularity_; }
+ Status GetCurrentTime(int64_t* unix_time) override;
+ // Converts seconds-since-Jan-01-1970 to a printable string
+ virtual std::string TimeToString(uint64_t time);
uint64_t GetPerfCounterFrequency() const { return perf_counter_frequency_; }
- static size_t GetSectorSize(const std::string& fname);
-
-private:
- // Returns true iff the named directory exists and is a directory.
- virtual bool DirExists(const std::string& dname);
-
- typedef VOID(WINAPI * FnGetSystemTimePreciseAsFileTime)(LPFILETIME);
+ private:
+ using FnGetSystemTimePreciseAsFileTime = VOID(WINAPI*)(LPFILETIME);
- Env* hosted_env_;
- size_t page_size_;
- size_t allocation_granularity_;
uint64_t perf_counter_frequency_;
uint64_t nano_seconds_per_period_;
FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_;
};
-class WinEnv : public Env {
-public:
- WinEnv();
-
- ~WinEnv();
-
- Status DeleteFile(const std::string& fname) override;
-
- Status Truncate(const std::string& fname, size_t size) override;
+class WinFileSystem : public FileSystem {
+ public:
+ static const std::shared_ptr<WinFileSystem>& Default();
+ WinFileSystem(const std::shared_ptr<SystemClock>& clock);
+ ~WinFileSystem() {}
+ static const char* kClassName() { return "WinFS"; }
+ const char* Name() const override { return kClassName(); }
+ const char* NickName() const { return kDefaultName(); }
- Status GetCurrentTime(int64_t* unix_time) override;
+ static size_t GetSectorSize(const std::string& fname);
+ size_t GetPageSize() const { return page_size_; }
+ size_t GetAllocationGranularity() const { return allocation_granularity_; }
- Status NewSequentialFile(const std::string& fname,
- std::unique_ptr<SequentialFile>* result,
- const EnvOptions& options) override;
-
- Status NewRandomAccessFile(const std::string& fname,
- std::unique_ptr<RandomAccessFile>* result,
- const EnvOptions& options) override;
-
- Status NewWritableFile(const std::string& fname,
- std::unique_ptr<WritableFile>* result,
- const EnvOptions& options) override;
-
- // Create an object that writes to a new file with the specified
- // name. Deletes any existing file with the same name and creates a
- // new file. On success, stores a pointer to the new file in
- // *result and returns OK. On failure stores nullptr in *result and
- // returns non-OK.
- //
- // The returned file will only be accessed by one thread at a time.
- Status ReopenWritableFile(const std::string& fname,
- std::unique_ptr<WritableFile>* result,
- const EnvOptions& options) override;
-
- // The returned file will only be accessed by one thread at a time.
- Status NewRandomRWFile(const std::string& fname,
- std::unique_ptr<RandomRWFile>* result,
- const EnvOptions& options) override;
-
- Status NewMemoryMappedFileBuffer(
+ IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
+ IODebugContext* dbg) override;
+
+ // Truncate the named file to the specified size.
+ IOStatus Truncate(const std::string& /*fname*/, size_t /*size*/,
+ const IOOptions& /*options*/,
+ IODebugContext* /*dbg*/) override;
+ IOStatus NewSequentialFile(const std::string& fname,
+ const FileOptions& file_opts,
+ std::unique_ptr<FSSequentialFile>* result,
+ IODebugContext* dbg) override;
+
+ IOStatus NewRandomAccessFile(const std::string& fname,
+ const FileOptions& options,
+ std::unique_ptr<FSRandomAccessFile>* result,
+ IODebugContext* /*dbg*/) override;
+ IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
+ std::unique_ptr<FSWritableFile>* r,
+ IODebugContext* dbg) override;
+ IOStatus ReopenWritableFile(const std::string& fname,
+ const FileOptions& options,
+ std::unique_ptr<FSWritableFile>* result,
+ IODebugContext* dbg) override;
+
+ IOStatus NewRandomRWFile(const std::string& fname,
+ const FileOptions& file_opts,
+ std::unique_ptr<FSRandomRWFile>* result,
+ IODebugContext* dbg) override;
+ IOStatus NewMemoryMappedFileBuffer(
const std::string& fname,
std::unique_ptr<MemoryMappedFileBuffer>* result) override;
- Status NewDirectory(const std::string& name,
- std::unique_ptr<Directory>* result) override;
-
- Status FileExists(const std::string& fname) override;
-
- Status GetChildren(const std::string& dir,
- std::vector<std::string>* result) override;
-
- Status CreateDir(const std::string& name) override;
-
- Status CreateDirIfMissing(const std::string& name) override;
-
- Status DeleteDir(const std::string& name) override;
-
- Status GetFileSize(const std::string& fname,
- uint64_t* size) override;
-
- Status GetFileModificationTime(const std::string& fname,
- uint64_t* file_mtime) override;
-
- Status RenameFile(const std::string& src,
- const std::string& target) override;
-
- Status LinkFile(const std::string& src,
- const std::string& target) override;
-
- Status NumFileLinks(const std::string& fname, uint64_t* count) override;
+ IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts,
+ std::unique_ptr<FSDirectory>* result,
+ IODebugContext* dbg) override;
+ IOStatus FileExists(const std::string& f, const IOOptions& io_opts,
+ IODebugContext* dbg) override;
+ IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
+ std::vector<std::string>* r,
+ IODebugContext* dbg) override;
+ IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
+ IODebugContext* dbg) override;
+
+ // Creates directory if missing. Return Ok if it exists, or successful in
+ // Creating.
+ IOStatus CreateDirIfMissing(const std::string& dirname,
+ const IOOptions& options,
+ IODebugContext* dbg) override;
+
+ // Delete the specified directory.
+ IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
+ IODebugContext* dbg) override;
+ // Store the size of fname in *file_size.
+ IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
+ uint64_t* file_size, IODebugContext* dbg) override;
+ // Store the last modification time of fname in *file_mtime.
+ IOStatus GetFileModificationTime(const std::string& fname,
+ const IOOptions& options,
+ uint64_t* file_mtime,
+ IODebugContext* dbg) override;
+ // Rename file src to target.
+ IOStatus RenameFile(const std::string& src, const std::string& target,
+ const IOOptions& options, IODebugContext* dbg) override;
+
+ // Hard Link file src to target.
+ IOStatus LinkFile(const std::string& /*src*/, const std::string& /*target*/,
+ const IOOptions& /*options*/,
+ IODebugContext* /*dbg*/) override;
+ IOStatus NumFileLinks(const std::string& /*fname*/,
+ const IOOptions& /*options*/, uint64_t* /*count*/,
+ IODebugContext* /*dbg*/) override;
+ IOStatus AreFilesSame(const std::string& /*first*/,
+ const std::string& /*second*/,
+ const IOOptions& /*options*/, bool* /*res*/,
+ IODebugContext* /*dbg*/) override;
+ IOStatus LockFile(const std::string& fname, const IOOptions& options,
+ FileLock** lock, IODebugContext* dbg) override;
+ IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
+ IODebugContext* dbg) override;
+ IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
+ IODebugContext* dbg) override;
+
+ // Create and returns a default logger (an instance of EnvLogger) for storing
+ // informational messages. Derived classes can override to provide custom
+ // logger.
+ IOStatus NewLogger(const std::string& fname, const IOOptions& io_opts,
+ std::shared_ptr<Logger>* result,
+ IODebugContext* dbg) override;
+ // Get full directory name for this db.
+ IOStatus GetAbsolutePath(const std::string& db_path, const IOOptions& options,
+ std::string* output_path,
+ IODebugContext* dbg) override;
+ IOStatus IsDirectory(const std::string& /*path*/, const IOOptions& options,
+ bool* is_dir, IODebugContext* /*dgb*/) override;
+ // This seems to clash with a macro on Windows, so #undef it here
+#undef GetFreeSpace
+ IOStatus GetFreeSpace(const std::string& /*path*/,
+ const IOOptions& /*options*/, uint64_t* /*diskfree*/,
+ IODebugContext* /*dbg*/) override;
+ FileOptions OptimizeForLogWrite(const FileOptions& file_options,
+ const DBOptions& db_options) const override;
+ FileOptions OptimizeForManifestRead(
+ const FileOptions& file_options) const override;
+ FileOptions OptimizeForManifestWrite(
+ const FileOptions& file_options) const override;
+
+ protected:
+ static uint64_t FileTimeToUnixTime(const FILETIME& ftTime);
+ // Returns true iff the named directory exists and is a directory.
- Status AreFilesSame(const std::string& first,
- const std::string& second, bool* res) override;
+ virtual bool DirExists(const std::string& dname);
+ // Helper for NewWritable and ReopenWritableFile
+ virtual IOStatus OpenWritableFile(const std::string& fname,
+ const FileOptions& options,
+ std::unique_ptr<FSWritableFile>* result,
+ bool reopen);
- Status LockFile(const std::string& lockFname, FileLock** lock) override;
+ private:
+ std::shared_ptr<SystemClock> clock_;
+ size_t page_size_;
+ size_t allocation_granularity_;
+};
- Status UnlockFile(FileLock* lock) override;
+// Designed for inheritance so can be re-used
+// but certain parts replaced
+class WinEnvIO {
+ public:
+ explicit WinEnvIO(Env* hosted_env);
- Status GetTestDirectory(std::string* result) override;
+ virtual ~WinEnvIO();
- Status NewLogger(const std::string& fname,
- std::shared_ptr<Logger>* result) override;
+ virtual Status GetHostName(char* name, uint64_t len);
- Status IsDirectory(const std::string& path, bool* is_dir) override;
+ private:
+ Env* hosted_env_;
+};
- uint64_t NowMicros() override;
+class WinEnv : public CompositeEnv {
+ public:
+ WinEnv();
- uint64_t NowNanos() override;
+ ~WinEnv();
+ static const char* kClassName() { return "WinEnv"; }
+ const char* Name() const override { return kClassName(); }
+ const char* NickName() const override { return kDefaultName(); }
Status GetHostName(char* name, uint64_t len) override;
- Status GetAbsolutePath(const std::string& db_path,
- std::string* output_path) override;
-
- std::string TimeToString(uint64_t secondsSince1970) override;
-
Status GetThreadList(std::vector<ThreadStatus>* thread_list) override;
- void Schedule(void(*function)(void*), void* arg, Env::Priority pri,
- void* tag, void(*unschedFunction)(void* arg)) override;
+ void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
+ void* tag, void (*unschedFunction)(void* arg)) override;
int UnSchedule(void* arg, Env::Priority pri) override;
- void StartThread(void(*function)(void* arg), void* arg) override;
+ void StartThread(void (*function)(void* arg), void* arg) override;
void WaitForJoin() override;
unsigned int GetThreadPoolQueueLen(Env::Priority pri) const override;
- uint64_t GetThreadID() const override;
-
- // This seems to clash with a macro on Windows, so #undef it here
-#undef GetFreeSpace
+ int ReserveThreads(int threads_to_be_reserved, Env::Priority pri) override;
- // Get the amount of free disk space
- Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override;
+ int ReleaseThreads(int threads_to_be_released, Env::Priority pri) override;
- void SleepForMicroseconds(int micros) override;
+ uint64_t GetThreadID() const override;
// Allow increasing the number of worker threads.
void SetBackgroundThreads(int num, Env::Priority pri) override;
void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri) override;
- EnvOptions OptimizeForManifestRead(
- const EnvOptions& env_options) const override;
-
- EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
- const DBOptions& db_options) const override;
-
- EnvOptions OptimizeForManifestWrite(
- const EnvOptions& env_options) const override;
-
-
-private:
-
+ private:
WinEnvIO winenv_io_;
WinEnvThreads winenv_threads_;
};
-} // namespace port
+} // namespace port
} // namespace ROCKSDB_NAMESPACE