2016-05-19 23:40:54 +00:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-15 23:03:42 +00:00
|
|
|
// 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).
|
2016-05-19 23:40:54 +00:00
|
|
|
// 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
|
2017-02-06 22:43:55 +00:00
|
|
|
#include <stdint.h>
|
2017-05-05 23:09:24 +00:00
|
|
|
#include <windows.h>
|
2017-02-06 22:43:55 +00:00
|
|
|
|
2016-05-19 23:40:54 +00:00
|
|
|
#include <mutex>
|
2017-02-06 22:43:55 +00:00
|
|
|
#include <string>
|
2021-01-06 18:48:24 +00:00
|
|
|
#include <vector>
|
2017-02-06 22:43:55 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
#include "env/composite_env_wrapper.h"
|
2021-06-29 13:51:11 +00:00
|
|
|
#include "port/port.h"
|
2021-01-06 18:48:24 +00:00
|
|
|
#include "rocksdb/env.h"
|
|
|
|
#include "rocksdb/file_system.h"
|
2021-01-26 06:07:26 +00:00
|
|
|
#include "rocksdb/system_clock.h"
|
2021-01-06 18:48:24 +00:00
|
|
|
#include "util/threadpool_imp.h"
|
2017-02-06 22:43:55 +00:00
|
|
|
|
|
|
|
#undef GetCurrentTime
|
|
|
|
#undef DeleteFile
|
2021-01-06 18:48:24 +00:00
|
|
|
#undef LoadLibrary
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2020-02-20 20:07:53 +00:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2016-05-19 23:40:54 +00:00
|
|
|
namespace port {
|
|
|
|
|
|
|
|
// Currently not designed for inheritance but rather a replacement
|
|
|
|
class WinEnvThreads {
|
2021-01-06 18:48:24 +00:00
|
|
|
public:
|
2016-05-19 23:40:54 +00:00
|
|
|
explicit WinEnvThreads(Env* hosted_env);
|
|
|
|
|
|
|
|
~WinEnvThreads();
|
|
|
|
|
|
|
|
WinEnvThreads(const WinEnvThreads&) = delete;
|
|
|
|
WinEnvThreads& operator=(const WinEnvThreads&) = delete;
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
|
|
|
|
void* tag, void (*unschedFunction)(void* arg));
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
int UnSchedule(void* arg, Env::Priority pri);
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
void StartThread(void (*function)(void* arg), void* arg);
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
void WaitForJoin();
|
|
|
|
|
|
|
|
unsigned int GetThreadPoolQueueLen(Env::Priority pri) const;
|
|
|
|
|
2022-07-09 02:48:09 +00:00
|
|
|
int ReserveThreads(int threads_to_be_reserved, Env::Priority pri);
|
|
|
|
|
|
|
|
int ReleaseThreads(int threads_to_be_released, Env::Priority pri);
|
|
|
|
|
2016-05-19 23:40:54 +00:00
|
|
|
static uint64_t gettid();
|
|
|
|
|
|
|
|
uint64_t GetThreadID() const;
|
|
|
|
|
|
|
|
// Allow increasing the number of worker threads.
|
|
|
|
void SetBackgroundThreads(int num, Env::Priority pri);
|
2017-05-23 18:04:25 +00:00
|
|
|
int GetBackgroundThreads(Env::Priority pri);
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri);
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
private:
|
2019-03-27 23:31:30 +00:00
|
|
|
Env* hosted_env_;
|
|
|
|
mutable std::mutex mu_;
|
2016-08-26 17:41:35 +00:00
|
|
|
std::vector<ThreadPoolImpl> thread_pools_;
|
2021-06-29 13:51:11 +00:00
|
|
|
std::vector<Thread> threads_to_join_;
|
2016-05-19 23:40:54 +00:00
|
|
|
};
|
|
|
|
|
2021-01-26 06:07:26 +00:00
|
|
|
class WinClock : public SystemClock {
|
2021-01-06 18:48:24 +00:00
|
|
|
public:
|
|
|
|
WinClock();
|
|
|
|
virtual ~WinClock() {}
|
2020-04-17 21:36:51 +00:00
|
|
|
|
2021-09-21 15:53:03 +00:00
|
|
|
static const char* kClassName() { return "WindowsClock"; }
|
2022-05-16 16:44:43 +00:00
|
|
|
const char* Name() const override { return kDefaultName(); }
|
|
|
|
const char* NickName() const override { return kClassName(); }
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-26 06:07:26 +00:00
|
|
|
uint64_t NowMicros() override;
|
|
|
|
|
|
|
|
uint64_t NowNanos() override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-26 06:07:26 +00:00
|
|
|
// 0 indicates not supported
|
|
|
|
uint64_t CPUMicros() override { return 0; }
|
|
|
|
void SleepForMicroseconds(int micros) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-26 06:07:26 +00:00
|
|
|
Status GetCurrentTime(int64_t* unix_time) override;
|
2021-01-06 18:48:24 +00:00
|
|
|
// Converts seconds-since-Jan-01-1970 to a printable string
|
2023-02-19 01:30:15 +00:00
|
|
|
std::string TimeToString(uint64_t time) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
uint64_t GetPerfCounterFrequency() const { return perf_counter_frequency_; }
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
private:
|
2021-09-07 18:31:12 +00:00
|
|
|
using FnGetSystemTimePreciseAsFileTime = VOID(WINAPI*)(LPFILETIME);
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2019-03-27 23:31:30 +00:00
|
|
|
uint64_t perf_counter_frequency_;
|
|
|
|
uint64_t nano_seconds_per_period_;
|
2016-05-19 23:40:54 +00:00
|
|
|
FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_;
|
|
|
|
};
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
class WinFileSystem : public FileSystem {
|
|
|
|
public:
|
|
|
|
static const std::shared_ptr<WinFileSystem>& Default();
|
2021-01-26 06:07:26 +00:00
|
|
|
WinFileSystem(const std::shared_ptr<SystemClock>& clock);
|
2021-01-06 18:48:24 +00:00
|
|
|
~WinFileSystem() {}
|
2021-11-02 16:06:02 +00:00
|
|
|
static const char* kClassName() { return "WinFS"; }
|
|
|
|
const char* Name() const override { return kClassName(); }
|
2023-02-19 01:30:15 +00:00
|
|
|
const char* NickName() const override { return kDefaultName(); }
|
2021-11-02 16:06:02 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
static size_t GetSectorSize(const std::string& fname);
|
|
|
|
size_t GetPageSize() const { return page_size_; }
|
|
|
|
size_t GetAllocationGranularity() const { return allocation_granularity_; }
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
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(
|
2019-03-27 23:31:30 +00:00
|
|
|
const std::string& fname,
|
|
|
|
std::unique_ptr<MemoryMappedFileBuffer>* result) override;
|
2018-05-24 22:05:00 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
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
|
2021-11-10 20:20:28 +00:00
|
|
|
// informational messages. Derived classes can override to provide custom
|
2021-01-06 18:48:24 +00:00
|
|
|
// 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;
|
2023-06-23 18:48:49 +00:00
|
|
|
void SupportedOps(int64_t& supported_ops) override { supported_ops = 0; }
|
2021-01-06 18:48:24 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
static uint64_t FileTimeToUnixTime(const FILETIME& ftTime);
|
|
|
|
// Returns true iff the named directory exists and is a directory.
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
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);
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
private:
|
2021-01-26 06:07:26 +00:00
|
|
|
std::shared_ptr<SystemClock> clock_;
|
2021-01-06 18:48:24 +00:00
|
|
|
size_t page_size_;
|
|
|
|
size_t allocation_granularity_;
|
|
|
|
};
|
2018-08-09 21:21:35 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
// Designed for inheritance so can be re-used
|
|
|
|
// but certain parts replaced
|
|
|
|
class WinEnvIO {
|
|
|
|
public:
|
|
|
|
explicit WinEnvIO(Env* hosted_env);
|
2018-03-06 19:47:42 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
virtual ~WinEnvIO();
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
virtual Status GetHostName(char* name, uint64_t len);
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
private:
|
|
|
|
Env* hosted_env_;
|
|
|
|
};
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
class WinEnv : public CompositeEnv {
|
|
|
|
public:
|
|
|
|
WinEnv();
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
~WinEnv();
|
2022-01-05 00:44:54 +00:00
|
|
|
static const char* kClassName() { return "WinEnv"; }
|
|
|
|
const char* Name() const override { return kClassName(); }
|
|
|
|
const char* NickName() const override { return kDefaultName(); }
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
Status GetHostName(char* name, uint64_t len) override;
|
|
|
|
|
2019-03-27 23:31:30 +00:00
|
|
|
Status GetThreadList(std::vector<ThreadStatus>* thread_list) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
void Schedule(void (*function)(void*), void* arg, Env::Priority pri,
|
|
|
|
void* tag, void (*unschedFunction)(void* arg)) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
int UnSchedule(void* arg, Env::Priority pri) override;
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
void StartThread(void (*function)(void* arg), void* arg) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
2020-09-23 19:54:29 +00:00
|
|
|
void WaitForJoin() override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
unsigned int GetThreadPoolQueueLen(Env::Priority pri) const override;
|
|
|
|
|
2022-07-09 02:48:09 +00:00
|
|
|
int ReserveThreads(int threads_to_be_reserved, Env::Priority pri) override;
|
|
|
|
|
|
|
|
int ReleaseThreads(int threads_to_be_released, Env::Priority pri) override;
|
|
|
|
|
2016-05-19 23:40:54 +00:00
|
|
|
uint64_t GetThreadID() const override;
|
|
|
|
|
|
|
|
// Allow increasing the number of worker threads.
|
|
|
|
void SetBackgroundThreads(int num, Env::Priority pri) override;
|
2017-05-23 18:04:25 +00:00
|
|
|
int GetBackgroundThreads(Env::Priority pri) override;
|
2016-05-19 23:40:54 +00:00
|
|
|
|
|
|
|
void IncBackgroundThreadsIfNeeded(int num, Env::Priority pri) override;
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
private:
|
2019-03-27 23:31:30 +00:00
|
|
|
WinEnvIO winenv_io_;
|
2016-08-26 17:41:35 +00:00
|
|
|
WinEnvThreads winenv_threads_;
|
2016-05-19 23:40:54 +00:00
|
|
|
};
|
|
|
|
|
2021-01-06 18:48:24 +00:00
|
|
|
} // namespace port
|
2020-02-20 20:07:53 +00:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|