| // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
| // This source code is licensed under both the GPLv2 (found in the |
| // COPYING file in the root directory) and Apache 2.0 License |
| // (found in the LICENSE.Apache file in the root directory). |
| // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. See the AUTHORS file for names of contributors. |
| // |
| // An Env is an interface used by the rocksdb implementation to access |
| // operating system functionality like the filesystem etc. Callers |
| // may wish to provide a custom Env object when opening a database to |
| // get fine gain control; e.g., to rate limit file system operations. |
| // |
| // All Env implementations are safe for concurrent access from |
| // 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> |
| |
| |
| #undef GetCurrentTime |
| #undef DeleteFile |
| #undef GetTickCount |
| |
| namespace rocksdb { |
| namespace port { |
| |
| // Currently not designed for inheritance but rather a replacement |
| class WinEnvThreads { |
| 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)); |
| |
| int UnSchedule(void* arg, Env::Priority pri); |
| |
| void StartThread(void(*function)(void* arg), void* arg); |
| |
| void WaitForJoin(); |
| |
| unsigned int GetThreadPoolQueueLen(Env::Priority pri) const; |
| |
| 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: |
| |
| Env* hosted_env_; |
| mutable std::mutex mu_; |
| std::vector<ThreadPoolImpl> thread_pools_; |
| std::vector<WindowsThread> 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); |
| |
| 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, |
| unique_ptr<RandomRWFile>* result, |
| const EnvOptions& options); |
| |
| 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); |
| |
| virtual Status CreateDir(const std::string& name); |
| |
| 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 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 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); |
| |
| 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; |
| |
| size_t GetPageSize() const { return page_size_; } |
| |
| size_t GetAllocationGranularity() const { return allocation_granularity_; } |
| |
| uint64_t GetPerfCounterFrequency() const { return perf_counter_frequency_; } |
| |
| private: |
| // Returns true iff the named directory exists and is a directory. |
| virtual bool DirExists(const std::string& dname); |
| |
| typedef VOID(WINAPI * FnGetSystemTimePreciseAsFileTime)(LPFILETIME); |
| |
| Env* hosted_env_; |
| size_t page_size_; |
| size_t allocation_granularity_; |
| uint64_t perf_counter_frequency_; |
| FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_; |
| }; |
| |
| class WinEnv : public Env { |
| public: |
| WinEnv(); |
| |
| ~WinEnv(); |
| |
| Status DeleteFile(const std::string& fname) override; |
| |
| Status GetCurrentTime(int64_t* unix_time) override; |
| |
| 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, |
| unique_ptr<RandomRWFile>* result, |
| const EnvOptions& options) 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 LockFile(const std::string& lockFname, |
| FileLock** lock) override; |
| |
| Status UnlockFile(FileLock* lock) override; |
| |
| Status GetTestDirectory(std::string* result) override; |
| |
| Status NewLogger(const std::string& fname, |
| std::shared_ptr<Logger>* result) override; |
| |
| uint64_t NowMicros() override; |
| |
| uint64_t NowNanos() override; |
| |
| 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; |
| |
| int UnSchedule(void* arg, Env::Priority pri) override; |
| |
| void StartThread(void(*function)(void* arg), void* arg) override; |
| |
| void WaitForJoin(); |
| |
| unsigned int GetThreadPoolQueueLen(Env::Priority pri) const override; |
| |
| uint64_t GetThreadID() const override; |
| |
| void SleepForMicroseconds(int micros) override; |
| |
| // Allow increasing the number of worker threads. |
| void SetBackgroundThreads(int num, Env::Priority pri) override; |
| int GetBackgroundThreads(Env::Priority pri) override; |
| |
| void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri) override; |
| |
| EnvOptions OptimizeForLogWrite(const EnvOptions& env_options, |
| const DBOptions& db_options) const override; |
| |
| EnvOptions OptimizeForManifestWrite( |
| const EnvOptions& env_options) const override; |
| |
| private: |
| |
| WinEnvIO winenv_io_; |
| WinEnvThreads winenv_threads_; |
| }; |
| |
| } // namespace port |
| } // namespace rocksdb |