1 // Copyright (c) 2019-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 #include "env/composite_env_wrapper.h"
7 #include "rocksdb/file_system.h"
8 #include "options/db_options.h"
9 #include "rocksdb/utilities/object_registry.h"
10 
11 namespace ROCKSDB_NAMESPACE {
12 
FileSystem()13 FileSystem::FileSystem() {}
14 
~FileSystem()15 FileSystem::~FileSystem() {}
16 
Load(const std::string & value,std::shared_ptr<FileSystem> * result)17 Status FileSystem::Load(const std::string& value,
18                         std::shared_ptr<FileSystem>* result) {
19   Status s;
20 #ifndef ROCKSDB_LITE
21   s = ObjectRegistry::NewInstance()->NewSharedObject<FileSystem>(value, result);
22 #else
23   (void)result;
24   s = Status::NotSupported("Cannot load FileSystem in LITE mode: ", value);
25 #endif
26   return s;
27 }
28 
ReuseWritableFile(const std::string & fname,const std::string & old_fname,const FileOptions & opts,std::unique_ptr<FSWritableFile> * result,IODebugContext * dbg)29 IOStatus FileSystem::ReuseWritableFile(const std::string& fname,
30                                        const std::string& old_fname,
31                                        const FileOptions& opts,
32                                        std::unique_ptr<FSWritableFile>* result,
33                                        IODebugContext* dbg) {
34   IOStatus s = RenameFile(old_fname, fname, opts.io_options, dbg);
35   if (!s.ok()) {
36     return s;
37   }
38   return NewWritableFile(fname, opts, result, dbg);
39 }
40 
OptimizeForLogRead(const FileOptions & file_options) const41 FileOptions FileSystem::OptimizeForLogRead(
42               const FileOptions& file_options) const {
43   FileOptions optimized_file_options(file_options);
44   optimized_file_options.use_direct_reads = false;
45   return optimized_file_options;
46 }
47 
OptimizeForManifestRead(const FileOptions & file_options) const48 FileOptions FileSystem::OptimizeForManifestRead(
49     const FileOptions& file_options) const {
50   FileOptions optimized_file_options(file_options);
51   optimized_file_options.use_direct_reads = false;
52   return optimized_file_options;
53 }
54 
OptimizeForLogWrite(const FileOptions & file_options,const DBOptions & db_options) const55 FileOptions FileSystem::OptimizeForLogWrite(const FileOptions& file_options,
56                                            const DBOptions& db_options) const {
57   FileOptions optimized_file_options(file_options);
58   optimized_file_options.bytes_per_sync = db_options.wal_bytes_per_sync;
59   optimized_file_options.writable_file_max_buffer_size =
60       db_options.writable_file_max_buffer_size;
61   return optimized_file_options;
62 }
63 
OptimizeForManifestWrite(const FileOptions & file_options) const64 FileOptions FileSystem::OptimizeForManifestWrite(
65     const FileOptions& file_options) const {
66   return file_options;
67 }
68 
OptimizeForCompactionTableWrite(const FileOptions & file_options,const ImmutableDBOptions & db_options) const69 FileOptions FileSystem::OptimizeForCompactionTableWrite(
70     const FileOptions& file_options,
71     const ImmutableDBOptions& db_options) const {
72   FileOptions optimized_file_options(file_options);
73   optimized_file_options.use_direct_writes =
74       db_options.use_direct_io_for_flush_and_compaction;
75   return optimized_file_options;
76 }
77 
OptimizeForCompactionTableRead(const FileOptions & file_options,const ImmutableDBOptions & db_options) const78 FileOptions FileSystem::OptimizeForCompactionTableRead(
79     const FileOptions& file_options,
80     const ImmutableDBOptions& db_options) const {
81   FileOptions optimized_file_options(file_options);
82   optimized_file_options.use_direct_reads = db_options.use_direct_reads;
83   return optimized_file_options;
84 }
85 
WriteStringToFile(FileSystem * fs,const Slice & data,const std::string & fname,bool should_sync)86 IOStatus WriteStringToFile(FileSystem* fs, const Slice& data,
87                            const std::string& fname, bool should_sync) {
88   std::unique_ptr<FSWritableFile> file;
89   EnvOptions soptions;
90   IOStatus s = fs->NewWritableFile(fname, soptions, &file, nullptr);
91   if (!s.ok()) {
92     return s;
93   }
94   s = file->Append(data, IOOptions(), nullptr);
95   if (s.ok() && should_sync) {
96     s = file->Sync(IOOptions(), nullptr);
97   }
98   if (!s.ok()) {
99     fs->DeleteFile(fname, IOOptions(), nullptr);
100   }
101   return s;
102 }
103 
ReadFileToString(FileSystem * fs,const std::string & fname,std::string * data)104 IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,
105                           std::string* data) {
106   FileOptions soptions;
107   data->clear();
108   std::unique_ptr<FSSequentialFile> file;
109   IOStatus s = status_to_io_status(
110       fs->NewSequentialFile(fname, soptions, &file, nullptr));
111   if (!s.ok()) {
112     return s;
113   }
114   static const int kBufferSize = 8192;
115   char* space = new char[kBufferSize];
116   while (true) {
117     Slice fragment;
118     s = file->Read(kBufferSize, IOOptions(), &fragment, space,
119                    nullptr);
120     if (!s.ok()) {
121       break;
122     }
123     data->append(fragment.data(), fragment.size());
124     if (fragment.empty()) {
125       break;
126     }
127   }
128   delete[] space;
129   return s;
130 }
131 
132 #ifdef OS_WIN
Default()133 std::shared_ptr<FileSystem> FileSystem::Default() {
134   static LegacyFileSystemWrapper default_fs(Env::Default());
135   static std::shared_ptr<LegacyFileSystemWrapper> default_fs_ptr(
136       &default_fs, [](LegacyFileSystemWrapper*) {});
137   return default_fs_ptr;
138 }
139 #endif
140 
141 }  // namespace ROCKSDB_NAMESPACE
142