env.cc 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. // Copyright (c) 2011-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. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "rocksdb/env.h"
  10. #include <sstream>
  11. #include <thread>
  12. #include "env/composite_env_wrapper.h"
  13. #include "env/emulated_clock.h"
  14. #include "env/mock_env.h"
  15. #include "env/unique_id_gen.h"
  16. #include "logging/env_logger.h"
  17. #include "memory/arena.h"
  18. #include "options/db_options.h"
  19. #include "port/port.h"
  20. #include "rocksdb/convenience.h"
  21. #include "rocksdb/options.h"
  22. #include "rocksdb/system_clock.h"
  23. #include "rocksdb/utilities/customizable_util.h"
  24. #include "rocksdb/utilities/object_registry.h"
  25. #include "rocksdb/utilities/options_type.h"
  26. #include "util/autovector.h"
  27. namespace ROCKSDB_NAMESPACE {
  28. namespace {
  29. static int RegisterBuiltinEnvs(ObjectLibrary& library,
  30. const std::string& /*arg*/) {
  31. library.AddFactory<Env>(MockEnv::kClassName(), [](const std::string& /*uri*/,
  32. std::unique_ptr<Env>* guard,
  33. std::string* /* errmsg */) {
  34. guard->reset(MockEnv::Create(Env::Default()));
  35. return guard->get();
  36. });
  37. library.AddFactory<Env>(
  38. CompositeEnvWrapper::kClassName(),
  39. [](const std::string& /*uri*/, std::unique_ptr<Env>* guard,
  40. std::string* /* errmsg */) {
  41. guard->reset(new CompositeEnvWrapper(Env::Default()));
  42. return guard->get();
  43. });
  44. size_t num_types;
  45. return static_cast<int>(library.GetFactoryCount(&num_types));
  46. }
  47. static void RegisterSystemEnvs() {
  48. static std::once_flag loaded;
  49. std::call_once(loaded, [&]() {
  50. RegisterBuiltinEnvs(*(ObjectLibrary::Default().get()), "");
  51. });
  52. }
  53. class LegacySystemClock : public SystemClock {
  54. private:
  55. Env* env_;
  56. public:
  57. explicit LegacySystemClock(Env* env) : env_(env) {}
  58. const char* Name() const override { return "LegacySystemClock"; }
  59. // Returns the number of micro-seconds since some fixed point in time.
  60. // It is often used as system time such as in GenericRateLimiter
  61. // and other places so a port needs to return system time in order to work.
  62. uint64_t NowMicros() override { return env_->NowMicros(); }
  63. // Returns the number of nano-seconds since some fixed point in time. Only
  64. // useful for computing deltas of time in one run.
  65. // Default implementation simply relies on NowMicros.
  66. // In platform-specific implementations, NowNanos() should return time points
  67. // that are MONOTONIC.
  68. uint64_t NowNanos() override { return env_->NowNanos(); }
  69. uint64_t CPUMicros() override { return CPUNanos() / 1000; }
  70. uint64_t CPUNanos() override { return env_->NowCPUNanos(); }
  71. // Sleep/delay the thread for the prescribed number of micro-seconds.
  72. void SleepForMicroseconds(int micros) override {
  73. env_->SleepForMicroseconds(micros);
  74. }
  75. // Get the number of seconds since the Epoch, 1970-01-01 00:00:00 (UTC).
  76. // Only overwrites *unix_time on success.
  77. Status GetCurrentTime(int64_t* unix_time) override {
  78. return env_->GetCurrentTime(unix_time);
  79. }
  80. // Converts seconds-since-Jan-01-1970 to a printable string
  81. std::string TimeToString(uint64_t time) override {
  82. return env_->TimeToString(time);
  83. }
  84. std::string SerializeOptions(const ConfigOptions& /*config_options*/,
  85. const std::string& /*prefix*/) const override {
  86. // We do not want the LegacySystemClock to appear in the serialized output.
  87. // This clock is an internal class for those who do not implement one and
  88. // would be part of the Env. As such, do not serialize it here.
  89. return "";
  90. }
  91. };
  92. class LegacySequentialFileWrapper : public FSSequentialFile {
  93. public:
  94. explicit LegacySequentialFileWrapper(
  95. std::unique_ptr<SequentialFile>&& _target)
  96. : target_(std::move(_target)) {}
  97. IOStatus Read(size_t n, const IOOptions& /*options*/, Slice* result,
  98. char* scratch, IODebugContext* /*dbg*/) override {
  99. return status_to_io_status(target_->Read(n, result, scratch));
  100. }
  101. IOStatus Skip(uint64_t n) override {
  102. return status_to_io_status(target_->Skip(n));
  103. }
  104. bool use_direct_io() const override { return target_->use_direct_io(); }
  105. size_t GetRequiredBufferAlignment() const override {
  106. return target_->GetRequiredBufferAlignment();
  107. }
  108. IOStatus InvalidateCache(size_t offset, size_t length) override {
  109. return status_to_io_status(target_->InvalidateCache(offset, length));
  110. }
  111. IOStatus PositionedRead(uint64_t offset, size_t n,
  112. const IOOptions& /*options*/, Slice* result,
  113. char* scratch, IODebugContext* /*dbg*/) override {
  114. return status_to_io_status(
  115. target_->PositionedRead(offset, n, result, scratch));
  116. }
  117. private:
  118. std::unique_ptr<SequentialFile> target_;
  119. };
  120. class LegacyRandomAccessFileWrapper : public FSRandomAccessFile {
  121. public:
  122. explicit LegacyRandomAccessFileWrapper(
  123. std::unique_ptr<RandomAccessFile>&& target)
  124. : target_(std::move(target)) {}
  125. IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
  126. Slice* result, char* scratch,
  127. IODebugContext* /*dbg*/) const override {
  128. return status_to_io_status(target_->Read(offset, n, result, scratch));
  129. }
  130. IOStatus MultiRead(FSReadRequest* fs_reqs, size_t num_reqs,
  131. const IOOptions& /*options*/,
  132. IODebugContext* /*dbg*/) override {
  133. std::vector<ReadRequest> reqs;
  134. Status status;
  135. reqs.reserve(num_reqs);
  136. for (size_t i = 0; i < num_reqs; ++i) {
  137. ReadRequest req;
  138. req.offset = fs_reqs[i].offset;
  139. req.len = fs_reqs[i].len;
  140. req.scratch = fs_reqs[i].scratch;
  141. req.status = Status::OK();
  142. reqs.emplace_back(std::move(req));
  143. }
  144. status = target_->MultiRead(reqs.data(), num_reqs);
  145. for (size_t i = 0; i < num_reqs; ++i) {
  146. fs_reqs[i].result = reqs[i].result;
  147. fs_reqs[i].status = status_to_io_status(std::move(reqs[i].status));
  148. }
  149. return status_to_io_status(std::move(status));
  150. }
  151. IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& /*options*/,
  152. IODebugContext* /*dbg*/) override {
  153. return status_to_io_status(target_->Prefetch(offset, n));
  154. }
  155. size_t GetUniqueId(char* id, size_t max_size) const override {
  156. return target_->GetUniqueId(id, max_size);
  157. }
  158. void Hint(AccessPattern pattern) override {
  159. target_->Hint((RandomAccessFile::AccessPattern)pattern);
  160. }
  161. bool use_direct_io() const override { return target_->use_direct_io(); }
  162. size_t GetRequiredBufferAlignment() const override {
  163. return target_->GetRequiredBufferAlignment();
  164. }
  165. IOStatus InvalidateCache(size_t offset, size_t length) override {
  166. return status_to_io_status(target_->InvalidateCache(offset, length));
  167. }
  168. IOStatus GetFileSize(uint64_t* result) override {
  169. auto status = target_->GetFileSize(result);
  170. return status_to_io_status(std::move(status));
  171. }
  172. private:
  173. std::unique_ptr<RandomAccessFile> target_;
  174. };
  175. class LegacyRandomRWFileWrapper : public FSRandomRWFile {
  176. public:
  177. explicit LegacyRandomRWFileWrapper(std::unique_ptr<RandomRWFile>&& target)
  178. : target_(std::move(target)) {}
  179. bool use_direct_io() const override { return target_->use_direct_io(); }
  180. size_t GetRequiredBufferAlignment() const override {
  181. return target_->GetRequiredBufferAlignment();
  182. }
  183. IOStatus Write(uint64_t offset, const Slice& data,
  184. const IOOptions& /*options*/,
  185. IODebugContext* /*dbg*/) override {
  186. return status_to_io_status(target_->Write(offset, data));
  187. }
  188. IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
  189. Slice* result, char* scratch,
  190. IODebugContext* /*dbg*/) const override {
  191. return status_to_io_status(target_->Read(offset, n, result, scratch));
  192. }
  193. IOStatus Flush(const IOOptions& /*options*/,
  194. IODebugContext* /*dbg*/) override {
  195. return status_to_io_status(target_->Flush());
  196. }
  197. IOStatus Sync(const IOOptions& /*options*/,
  198. IODebugContext* /*dbg*/) override {
  199. return status_to_io_status(target_->Sync());
  200. }
  201. IOStatus Fsync(const IOOptions& /*options*/,
  202. IODebugContext* /*dbg*/) override {
  203. return status_to_io_status(target_->Fsync());
  204. }
  205. IOStatus Close(const IOOptions& /*options*/,
  206. IODebugContext* /*dbg*/) override {
  207. return status_to_io_status(target_->Close());
  208. }
  209. private:
  210. std::unique_ptr<RandomRWFile> target_;
  211. };
  212. class LegacyWritableFileWrapper : public FSWritableFile {
  213. public:
  214. explicit LegacyWritableFileWrapper(std::unique_ptr<WritableFile>&& _target)
  215. : target_(std::move(_target)) {}
  216. IOStatus Append(const Slice& data, const IOOptions& /*options*/,
  217. IODebugContext* /*dbg*/) override {
  218. return status_to_io_status(target_->Append(data));
  219. }
  220. IOStatus Append(const Slice& data, const IOOptions& /*options*/,
  221. const DataVerificationInfo& /*verification_info*/,
  222. IODebugContext* /*dbg*/) override {
  223. return status_to_io_status(target_->Append(data));
  224. }
  225. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  226. const IOOptions& /*options*/,
  227. IODebugContext* /*dbg*/) override {
  228. return status_to_io_status(target_->PositionedAppend(data, offset));
  229. }
  230. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  231. const IOOptions& /*options*/,
  232. const DataVerificationInfo& /*verification_info*/,
  233. IODebugContext* /*dbg*/) override {
  234. return status_to_io_status(target_->PositionedAppend(data, offset));
  235. }
  236. IOStatus Truncate(uint64_t size, const IOOptions& /*options*/,
  237. IODebugContext* /*dbg*/) override {
  238. return status_to_io_status(target_->Truncate(size));
  239. }
  240. IOStatus Close(const IOOptions& /*options*/,
  241. IODebugContext* /*dbg*/) override {
  242. return status_to_io_status(target_->Close());
  243. }
  244. IOStatus Flush(const IOOptions& /*options*/,
  245. IODebugContext* /*dbg*/) override {
  246. return status_to_io_status(target_->Flush());
  247. }
  248. IOStatus Sync(const IOOptions& /*options*/,
  249. IODebugContext* /*dbg*/) override {
  250. return status_to_io_status(target_->Sync());
  251. }
  252. IOStatus Fsync(const IOOptions& /*options*/,
  253. IODebugContext* /*dbg*/) override {
  254. return status_to_io_status(target_->Fsync());
  255. }
  256. bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
  257. bool use_direct_io() const override { return target_->use_direct_io(); }
  258. size_t GetRequiredBufferAlignment() const override {
  259. return target_->GetRequiredBufferAlignment();
  260. }
  261. void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
  262. target_->SetWriteLifeTimeHint(hint);
  263. }
  264. Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
  265. return target_->GetWriteLifeTimeHint();
  266. }
  267. uint64_t GetFileSize(const IOOptions& /*options*/,
  268. IODebugContext* /*dbg*/) override {
  269. return target_->GetFileSize();
  270. }
  271. void SetPreallocationBlockSize(size_t size) override {
  272. target_->SetPreallocationBlockSize(size);
  273. }
  274. void GetPreallocationStatus(size_t* block_size,
  275. size_t* last_allocated_block) override {
  276. target_->GetPreallocationStatus(block_size, last_allocated_block);
  277. }
  278. size_t GetUniqueId(char* id, size_t max_size) const override {
  279. return target_->GetUniqueId(id, max_size);
  280. }
  281. IOStatus InvalidateCache(size_t offset, size_t length) override {
  282. return status_to_io_status(target_->InvalidateCache(offset, length));
  283. }
  284. IOStatus RangeSync(uint64_t offset, uint64_t nbytes,
  285. const IOOptions& /*options*/,
  286. IODebugContext* /*dbg*/) override {
  287. return status_to_io_status(target_->RangeSync(offset, nbytes));
  288. }
  289. void PrepareWrite(size_t offset, size_t len, const IOOptions& /*options*/,
  290. IODebugContext* /*dbg*/) override {
  291. target_->PrepareWrite(offset, len);
  292. }
  293. IOStatus Allocate(uint64_t offset, uint64_t len, const IOOptions& /*options*/,
  294. IODebugContext* /*dbg*/) override {
  295. return status_to_io_status(target_->Allocate(offset, len));
  296. }
  297. private:
  298. std::unique_ptr<WritableFile> target_;
  299. };
  300. class LegacyDirectoryWrapper : public FSDirectory {
  301. public:
  302. explicit LegacyDirectoryWrapper(std::unique_ptr<Directory>&& target)
  303. : target_(std::move(target)) {}
  304. IOStatus Fsync(const IOOptions& /*options*/,
  305. IODebugContext* /*dbg*/) override {
  306. return status_to_io_status(target_->Fsync());
  307. }
  308. IOStatus Close(const IOOptions& /*options*/,
  309. IODebugContext* /*dbg*/) override {
  310. return status_to_io_status(target_->Close());
  311. }
  312. size_t GetUniqueId(char* id, size_t max_size) const override {
  313. return target_->GetUniqueId(id, max_size);
  314. }
  315. private:
  316. std::unique_ptr<Directory> target_;
  317. };
  318. // A helper class to make legacy `Env` implementations be backward compatible
  319. // now that all `Env` implementations are expected to have a `FileSystem` type
  320. // member `file_system_` and a `SystemClock` type member `clock_`.
  321. // This class wraps a legacy `Env` object and expose its file system related
  322. // APIs as a `FileSystem` interface. Also check `LegacySystemClock` that does
  323. // the same thing for the clock related APIs.
  324. class LegacyFileSystemWrapper : public FileSystem {
  325. public:
  326. // Initialize an EnvWrapper that delegates all calls to *t
  327. explicit LegacyFileSystemWrapper(Env* t) : target_(t) {}
  328. ~LegacyFileSystemWrapper() override = default;
  329. static const char* kClassName() { return "LegacyFileSystem"; }
  330. const char* Name() const override { return kClassName(); }
  331. // Return the target to which this Env forwards all calls
  332. Env* target() const { return target_; }
  333. // The following text is boilerplate that forwards all methods to target()
  334. IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
  335. std::unique_ptr<FSSequentialFile>* r,
  336. IODebugContext* /*dbg*/) override {
  337. std::unique_ptr<SequentialFile> file;
  338. Status s = target_->NewSequentialFile(f, &file, file_opts);
  339. if (s.ok()) {
  340. r->reset(new LegacySequentialFileWrapper(std::move(file)));
  341. }
  342. return status_to_io_status(std::move(s));
  343. }
  344. IOStatus NewRandomAccessFile(const std::string& f,
  345. const FileOptions& file_opts,
  346. std::unique_ptr<FSRandomAccessFile>* r,
  347. IODebugContext* /*dbg*/) override {
  348. std::unique_ptr<RandomAccessFile> file;
  349. Status s = target_->NewRandomAccessFile(f, &file, file_opts);
  350. if (s.ok()) {
  351. r->reset(new LegacyRandomAccessFileWrapper(std::move(file)));
  352. }
  353. return status_to_io_status(std::move(s));
  354. }
  355. IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
  356. std::unique_ptr<FSWritableFile>* r,
  357. IODebugContext* /*dbg*/) override {
  358. std::unique_ptr<WritableFile> file;
  359. Status s = target_->NewWritableFile(f, &file, file_opts);
  360. if (s.ok()) {
  361. r->reset(new LegacyWritableFileWrapper(std::move(file)));
  362. }
  363. return status_to_io_status(std::move(s));
  364. }
  365. IOStatus ReopenWritableFile(const std::string& fname,
  366. const FileOptions& file_opts,
  367. std::unique_ptr<FSWritableFile>* result,
  368. IODebugContext* /*dbg*/) override {
  369. std::unique_ptr<WritableFile> file;
  370. Status s = target_->ReopenWritableFile(fname, &file, file_opts);
  371. if (s.ok()) {
  372. result->reset(new LegacyWritableFileWrapper(std::move(file)));
  373. }
  374. return status_to_io_status(std::move(s));
  375. }
  376. IOStatus ReuseWritableFile(const std::string& fname,
  377. const std::string& old_fname,
  378. const FileOptions& file_opts,
  379. std::unique_ptr<FSWritableFile>* r,
  380. IODebugContext* /*dbg*/) override {
  381. std::unique_ptr<WritableFile> file;
  382. Status s = target_->ReuseWritableFile(fname, old_fname, &file, file_opts);
  383. if (s.ok()) {
  384. r->reset(new LegacyWritableFileWrapper(std::move(file)));
  385. }
  386. return status_to_io_status(std::move(s));
  387. }
  388. IOStatus NewRandomRWFile(const std::string& fname,
  389. const FileOptions& file_opts,
  390. std::unique_ptr<FSRandomRWFile>* result,
  391. IODebugContext* /*dbg*/) override {
  392. std::unique_ptr<RandomRWFile> file;
  393. Status s = target_->NewRandomRWFile(fname, &file, file_opts);
  394. if (s.ok()) {
  395. result->reset(new LegacyRandomRWFileWrapper(std::move(file)));
  396. }
  397. return status_to_io_status(std::move(s));
  398. }
  399. IOStatus NewMemoryMappedFileBuffer(
  400. const std::string& fname,
  401. std::unique_ptr<MemoryMappedFileBuffer>* result) override {
  402. return status_to_io_status(
  403. target_->NewMemoryMappedFileBuffer(fname, result));
  404. }
  405. IOStatus NewDirectory(const std::string& name, const IOOptions& /*io_opts*/,
  406. std::unique_ptr<FSDirectory>* result,
  407. IODebugContext* /*dbg*/) override {
  408. std::unique_ptr<Directory> dir;
  409. Status s = target_->NewDirectory(name, &dir);
  410. if (s.ok()) {
  411. result->reset(new LegacyDirectoryWrapper(std::move(dir)));
  412. }
  413. return status_to_io_status(std::move(s));
  414. }
  415. IOStatus FileExists(const std::string& f, const IOOptions& /*io_opts*/,
  416. IODebugContext* /*dbg*/) override {
  417. return status_to_io_status(target_->FileExists(f));
  418. }
  419. IOStatus GetChildren(const std::string& dir, const IOOptions& /*io_opts*/,
  420. std::vector<std::string>* r,
  421. IODebugContext* /*dbg*/) override {
  422. return status_to_io_status(target_->GetChildren(dir, r));
  423. }
  424. IOStatus GetChildrenFileAttributes(const std::string& dir,
  425. const IOOptions& /*options*/,
  426. std::vector<FileAttributes>* result,
  427. IODebugContext* /*dbg*/) override {
  428. return status_to_io_status(target_->GetChildrenFileAttributes(dir, result));
  429. }
  430. IOStatus DeleteFile(const std::string& f, const IOOptions& /*options*/,
  431. IODebugContext* /*dbg*/) override {
  432. return status_to_io_status(target_->DeleteFile(f));
  433. }
  434. IOStatus Truncate(const std::string& fname, size_t size,
  435. const IOOptions& /*options*/,
  436. IODebugContext* /*dbg*/) override {
  437. return status_to_io_status(target_->Truncate(fname, size));
  438. }
  439. IOStatus CreateDir(const std::string& d, const IOOptions& /*options*/,
  440. IODebugContext* /*dbg*/) override {
  441. return status_to_io_status(target_->CreateDir(d));
  442. }
  443. IOStatus CreateDirIfMissing(const std::string& d,
  444. const IOOptions& /*options*/,
  445. IODebugContext* /*dbg*/) override {
  446. return status_to_io_status(target_->CreateDirIfMissing(d));
  447. }
  448. IOStatus DeleteDir(const std::string& d, const IOOptions& /*options*/,
  449. IODebugContext* /*dbg*/) override {
  450. return status_to_io_status(target_->DeleteDir(d));
  451. }
  452. IOStatus GetFileSize(const std::string& f, const IOOptions& /*options*/,
  453. uint64_t* s, IODebugContext* /*dbg*/) override {
  454. return status_to_io_status(target_->GetFileSize(f, s));
  455. }
  456. IOStatus GetFileModificationTime(const std::string& fname,
  457. const IOOptions& /*options*/,
  458. uint64_t* file_mtime,
  459. IODebugContext* /*dbg*/) override {
  460. return status_to_io_status(
  461. target_->GetFileModificationTime(fname, file_mtime));
  462. }
  463. IOStatus GetAbsolutePath(const std::string& db_path,
  464. const IOOptions& /*options*/,
  465. std::string* output_path,
  466. IODebugContext* /*dbg*/) override {
  467. return status_to_io_status(target_->GetAbsolutePath(db_path, output_path));
  468. }
  469. IOStatus RenameFile(const std::string& s, const std::string& t,
  470. const IOOptions& /*options*/,
  471. IODebugContext* /*dbg*/) override {
  472. return status_to_io_status(target_->RenameFile(s, t));
  473. }
  474. IOStatus LinkFile(const std::string& s, const std::string& t,
  475. const IOOptions& /*options*/,
  476. IODebugContext* /*dbg*/) override {
  477. return status_to_io_status(target_->LinkFile(s, t));
  478. }
  479. IOStatus NumFileLinks(const std::string& fname, const IOOptions& /*options*/,
  480. uint64_t* count, IODebugContext* /*dbg*/) override {
  481. return status_to_io_status(target_->NumFileLinks(fname, count));
  482. }
  483. IOStatus AreFilesSame(const std::string& first, const std::string& second,
  484. const IOOptions& /*options*/, bool* res,
  485. IODebugContext* /*dbg*/) override {
  486. return status_to_io_status(target_->AreFilesSame(first, second, res));
  487. }
  488. IOStatus LockFile(const std::string& f, const IOOptions& /*options*/,
  489. FileLock** l, IODebugContext* /*dbg*/) override {
  490. return status_to_io_status(target_->LockFile(f, l));
  491. }
  492. IOStatus UnlockFile(FileLock* l, const IOOptions& /*options*/,
  493. IODebugContext* /*dbg*/) override {
  494. return status_to_io_status(target_->UnlockFile(l));
  495. }
  496. IOStatus GetTestDirectory(const IOOptions& /*options*/, std::string* path,
  497. IODebugContext* /*dbg*/) override {
  498. return status_to_io_status(target_->GetTestDirectory(path));
  499. }
  500. IOStatus NewLogger(const std::string& fname, const IOOptions& /*options*/,
  501. std::shared_ptr<Logger>* result,
  502. IODebugContext* /*dbg*/) override {
  503. return status_to_io_status(target_->NewLogger(fname, result));
  504. }
  505. void SanitizeFileOptions(FileOptions* opts) const override {
  506. target_->SanitizeEnvOptions(opts);
  507. }
  508. FileOptions OptimizeForLogRead(
  509. const FileOptions& file_options) const override {
  510. return target_->OptimizeForLogRead(file_options);
  511. }
  512. FileOptions OptimizeForManifestRead(
  513. const FileOptions& file_options) const override {
  514. return target_->OptimizeForManifestRead(file_options);
  515. }
  516. FileOptions OptimizeForLogWrite(const FileOptions& file_options,
  517. const DBOptions& db_options) const override {
  518. return target_->OptimizeForLogWrite(file_options, db_options);
  519. }
  520. FileOptions OptimizeForManifestWrite(
  521. const FileOptions& file_options) const override {
  522. return target_->OptimizeForManifestWrite(file_options);
  523. }
  524. FileOptions OptimizeForCompactionTableWrite(
  525. const FileOptions& file_options,
  526. const ImmutableDBOptions& immutable_ops) const override {
  527. return target_->OptimizeForCompactionTableWrite(file_options,
  528. immutable_ops);
  529. }
  530. FileOptions OptimizeForCompactionTableRead(
  531. const FileOptions& file_options,
  532. const ImmutableDBOptions& db_options) const override {
  533. return target_->OptimizeForCompactionTableRead(file_options, db_options);
  534. }
  535. FileOptions OptimizeForBlobFileRead(
  536. const FileOptions& file_options,
  537. const ImmutableDBOptions& db_options) const override {
  538. return target_->OptimizeForBlobFileRead(file_options, db_options);
  539. }
  540. #ifdef GetFreeSpace
  541. #undef GetFreeSpace
  542. #endif
  543. IOStatus GetFreeSpace(const std::string& path, const IOOptions& /*options*/,
  544. uint64_t* diskfree, IODebugContext* /*dbg*/) override {
  545. return status_to_io_status(target_->GetFreeSpace(path, diskfree));
  546. }
  547. IOStatus IsDirectory(const std::string& path, const IOOptions& /*options*/,
  548. bool* is_dir, IODebugContext* /*dbg*/) override {
  549. return status_to_io_status(target_->IsDirectory(path, is_dir));
  550. }
  551. std::string SerializeOptions(const ConfigOptions& /*config_options*/,
  552. const std::string& /*prefix*/) const override {
  553. // We do not want the LegacyFileSystem to appear in the serialized output.
  554. // This clock is an internal class for those who do not implement one and
  555. // would be part of the Env. As such, do not serialize it here.
  556. return "";
  557. }
  558. private:
  559. Env* target_;
  560. };
  561. } // end anonymous namespace
  562. Env::Env() : thread_status_updater_(nullptr) {
  563. file_system_ = std::make_shared<LegacyFileSystemWrapper>(this);
  564. system_clock_ = std::make_shared<LegacySystemClock>(this);
  565. }
  566. Env::Env(const std::shared_ptr<FileSystem>& fs)
  567. : thread_status_updater_(nullptr), file_system_(fs) {
  568. system_clock_ = std::make_shared<LegacySystemClock>(this);
  569. }
  570. Env::Env(const std::shared_ptr<FileSystem>& fs,
  571. const std::shared_ptr<SystemClock>& clock)
  572. : thread_status_updater_(nullptr), file_system_(fs), system_clock_(clock) {}
  573. Env::~Env() = default;
  574. Status Env::NewLogger(const std::string& fname,
  575. std::shared_ptr<Logger>* result) {
  576. return NewEnvLogger(fname, this, result);
  577. }
  578. Status Env::CreateFromString(const ConfigOptions& config_options,
  579. const std::string& value, Env** result) {
  580. Env* base = Env::Default();
  581. if (value.empty() || base->IsInstanceOf(value)) {
  582. *result = base;
  583. return Status::OK();
  584. } else {
  585. RegisterSystemEnvs();
  586. Env* env = *result;
  587. Status s = LoadStaticObject<Env>(config_options, value, &env);
  588. if (s.ok()) {
  589. *result = env;
  590. }
  591. return s;
  592. }
  593. }
  594. Status Env::CreateFromString(const ConfigOptions& config_options,
  595. const std::string& value, Env** result,
  596. std::shared_ptr<Env>* guard) {
  597. assert(result);
  598. assert(guard != nullptr);
  599. std::unique_ptr<Env> uniq;
  600. Env* env = *result;
  601. std::string id;
  602. std::unordered_map<std::string, std::string> opt_map;
  603. Status status =
  604. Customizable::GetOptionsMap(config_options, env, value, &id, &opt_map);
  605. if (!status.ok()) { // GetOptionsMap failed
  606. return status;
  607. }
  608. Env* base = Env::Default();
  609. if (id.empty() || base->IsInstanceOf(id)) {
  610. env = base;
  611. status = Status::OK();
  612. } else {
  613. RegisterSystemEnvs();
  614. // First, try to load the Env as a unique object.
  615. status = config_options.registry->NewObject<Env>(id, &env, &uniq);
  616. }
  617. if (config_options.ignore_unsupported_options && status.IsNotSupported()) {
  618. status = Status::OK();
  619. } else if (status.ok()) {
  620. status = Customizable::ConfigureNewObject(config_options, env, opt_map);
  621. }
  622. if (status.ok()) {
  623. guard->reset(uniq.release());
  624. *result = env;
  625. }
  626. return status;
  627. }
  628. Status Env::CreateFromUri(const ConfigOptions& config_options,
  629. const std::string& env_uri, const std::string& fs_uri,
  630. Env** result, std::shared_ptr<Env>* guard) {
  631. *result = config_options.env;
  632. if (env_uri.empty() && fs_uri.empty()) {
  633. // Neither specified. Use the default
  634. guard->reset();
  635. return Status::OK();
  636. } else if (!env_uri.empty() && !fs_uri.empty()) {
  637. // Both specified. Cannot choose. Return Invalid
  638. return Status::InvalidArgument("cannot specify both fs_uri and env_uri");
  639. } else if (fs_uri.empty()) { // Only have an ENV URI. Create an Env from it
  640. return CreateFromString(config_options, env_uri, result, guard);
  641. } else {
  642. std::shared_ptr<FileSystem> fs;
  643. Status s = FileSystem::CreateFromString(config_options, fs_uri, &fs);
  644. if (s.ok()) {
  645. guard->reset(new CompositeEnvWrapper(*result, fs));
  646. *result = guard->get();
  647. }
  648. return s;
  649. }
  650. }
  651. std::string Env::PriorityToString(Env::Priority priority) {
  652. switch (priority) {
  653. case Env::Priority::BOTTOM:
  654. return "Bottom";
  655. case Env::Priority::LOW:
  656. return "Low";
  657. case Env::Priority::HIGH:
  658. return "High";
  659. case Env::Priority::USER:
  660. return "User";
  661. case Env::Priority::TOTAL:
  662. assert(false);
  663. }
  664. return "Invalid";
  665. }
  666. std::string Env::IOActivityToString(IOActivity activity) {
  667. switch (activity) {
  668. case Env::IOActivity::kFlush:
  669. return "Flush";
  670. case Env::IOActivity::kCompaction:
  671. return "Compaction";
  672. case Env::IOActivity::kDBOpen:
  673. return "DBOpen";
  674. case Env::IOActivity::kGet:
  675. return "Get";
  676. case Env::IOActivity::kMultiGet:
  677. return "MultiGet";
  678. case Env::IOActivity::kDBIterator:
  679. return "DBIterator";
  680. case Env::IOActivity::kVerifyDBChecksum:
  681. return "VerifyDBChecksum";
  682. case Env::IOActivity::kVerifyFileChecksums:
  683. return "VerifyFileChecksums";
  684. case Env::IOActivity::kGetEntity:
  685. return "GetEntity";
  686. case Env::IOActivity::kMultiGetEntity:
  687. return "MultiGetEntity";
  688. case Env::IOActivity::kGetFileChecksumsFromCurrentManifest:
  689. return "GetFileChecksumsFromCurrentManifest";
  690. case Env::IOActivity::kUnknown:
  691. return "Unknown";
  692. default:
  693. int activityIndex = static_cast<int>(activity);
  694. if (activityIndex >=
  695. static_cast<int>(Env::IOActivity::kFirstCustomIOActivity) &&
  696. activityIndex <=
  697. static_cast<int>(Env::IOActivity::kLastCustomIOActivity)) {
  698. std::stringstream ss;
  699. ss << std::hex << std::uppercase << activityIndex;
  700. return "CustomIOActivity" + ss.str();
  701. }
  702. return "Invalid";
  703. };
  704. assert(false);
  705. return "Invalid";
  706. }
  707. uint64_t Env::GetThreadID() const {
  708. std::hash<std::thread::id> hasher;
  709. return hasher(std::this_thread::get_id());
  710. }
  711. Status Env::ReuseWritableFile(const std::string& fname,
  712. const std::string& old_fname,
  713. std::unique_ptr<WritableFile>* result,
  714. const EnvOptions& options) {
  715. Status s = RenameFile(old_fname, fname);
  716. if (!s.ok()) {
  717. return s;
  718. }
  719. return NewWritableFile(fname, result, options);
  720. }
  721. Status Env::GetChildrenFileAttributes(const std::string& dir,
  722. std::vector<FileAttributes>* result) {
  723. assert(result != nullptr);
  724. std::vector<std::string> child_fnames;
  725. Status s = GetChildren(dir, &child_fnames);
  726. if (!s.ok()) {
  727. return s;
  728. }
  729. result->resize(child_fnames.size());
  730. size_t result_size = 0;
  731. for (size_t i = 0; i < child_fnames.size(); ++i) {
  732. const std::string path = dir + "/" + child_fnames[i];
  733. if (!(s = GetFileSize(path, &(*result)[result_size].size_bytes)).ok()) {
  734. if (FileExists(path).IsNotFound()) {
  735. // The file may have been deleted since we listed the directory
  736. continue;
  737. }
  738. return s;
  739. }
  740. (*result)[result_size].name = std::move(child_fnames[i]);
  741. result_size++;
  742. }
  743. result->resize(result_size);
  744. return Status::OK();
  745. }
  746. Status Env::GetHostNameString(std::string* result) {
  747. std::array<char, kMaxHostNameLen> hostname_buf{};
  748. Status s = GetHostName(hostname_buf.data(), hostname_buf.size());
  749. if (s.ok()) {
  750. hostname_buf[hostname_buf.size() - 1] = '\0';
  751. result->assign(hostname_buf.data());
  752. }
  753. return s;
  754. }
  755. std::string Env::GenerateUniqueId() {
  756. std::string result;
  757. bool success = port::GenerateRfcUuid(&result);
  758. if (!success) {
  759. // Fall back on our own way of generating a unique ID and adapt it to
  760. // RFC 4122 variant 1 version 4 (a random ID).
  761. // https://en.wikipedia.org/wiki/Universally_unique_identifier
  762. // We already tried GenerateRfcUuid so no need to try it again in
  763. // GenerateRawUniqueId
  764. constexpr bool exclude_port_uuid = true;
  765. uint64_t upper, lower;
  766. GenerateRawUniqueId(&upper, &lower, exclude_port_uuid);
  767. // Set 4-bit version to 4
  768. upper = (upper & (~uint64_t{0xf000})) | 0x4000;
  769. // Set unary-encoded variant to 1 (0b10)
  770. lower = (lower & (~(uint64_t{3} << 62))) | (uint64_t{2} << 62);
  771. // Use 36 character format of RFC 4122
  772. result.resize(36U);
  773. char* buf = result.data();
  774. PutBaseChars<16>(&buf, 8, upper >> 32, /*!uppercase*/ false);
  775. *(buf++) = '-';
  776. PutBaseChars<16>(&buf, 4, upper >> 16, /*!uppercase*/ false);
  777. *(buf++) = '-';
  778. PutBaseChars<16>(&buf, 4, upper, /*!uppercase*/ false);
  779. *(buf++) = '-';
  780. PutBaseChars<16>(&buf, 4, lower >> 48, /*!uppercase*/ false);
  781. *(buf++) = '-';
  782. PutBaseChars<16>(&buf, 12, lower, /*!uppercase*/ false);
  783. assert(buf == &result[36]);
  784. // Verify variant 1 version 4
  785. assert(result[14] == '4');
  786. assert(result[19] == '8' || result[19] == '9' || result[19] == 'a' ||
  787. result[19] == 'b');
  788. }
  789. return result;
  790. }
  791. SequentialFile::~SequentialFile() = default;
  792. RandomAccessFile::~RandomAccessFile() = default;
  793. WritableFile::~WritableFile() = default;
  794. MemoryMappedFileBuffer::~MemoryMappedFileBuffer() = default;
  795. // This const variable can be used in public headers without introducing the
  796. // possibility of ODR violations due to varying macro definitions.
  797. const InfoLogLevel Logger::kDefaultLogLevel =
  798. #ifdef NDEBUG
  799. INFO_LEVEL;
  800. #else
  801. DEBUG_LEVEL;
  802. #endif // NDEBUG
  803. Logger::~Logger() = default;
  804. Status Logger::Close() {
  805. if (!closed_) {
  806. closed_ = true;
  807. return CloseImpl();
  808. } else {
  809. return Status::OK();
  810. }
  811. }
  812. Status Logger::CloseImpl() { return Status::NotSupported(); }
  813. FileLock::~FileLock() = default;
  814. void LogFlush(Logger* info_log) {
  815. if (info_log) {
  816. info_log->Flush();
  817. }
  818. }
  819. static void Logv(Logger* info_log, const char* format, va_list ap) {
  820. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
  821. info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
  822. }
  823. }
  824. void Log(Logger* info_log, const char* format, ...) {
  825. va_list ap;
  826. va_start(ap, format);
  827. Logv(info_log, format, ap);
  828. va_end(ap);
  829. }
  830. void Logger::Logv(const InfoLogLevel log_level, const char* format,
  831. va_list ap) {
  832. static const char* kInfoLogLevelNames[5] = {"DEBUG", "INFO", "WARN", "ERROR",
  833. "FATAL"};
  834. if (log_level < log_level_) {
  835. return;
  836. }
  837. if (log_level == InfoLogLevel::INFO_LEVEL) {
  838. // Doesn't print log level if it is INFO level.
  839. // This is to avoid unexpected performance regression after we add
  840. // the feature of log level. All the logs before we add the feature
  841. // are INFO level. We don't want to add extra costs to those existing
  842. // logging.
  843. Logv(format, ap);
  844. } else if (log_level == InfoLogLevel::HEADER_LEVEL) {
  845. LogHeader(format, ap);
  846. } else {
  847. char new_format[500];
  848. snprintf(new_format, sizeof(new_format) - 1, "[%s] %s",
  849. kInfoLogLevelNames[log_level], format);
  850. Logv(new_format, ap);
  851. }
  852. if (log_level >= InfoLogLevel::WARN_LEVEL &&
  853. log_level != InfoLogLevel::HEADER_LEVEL) {
  854. // Log messages with severity of warning or higher should be rare and are
  855. // sometimes followed by an unclean crash. We want to be sure important
  856. // messages are not lost in an application buffer when that happens.
  857. Flush();
  858. }
  859. }
  860. static void Logv(const InfoLogLevel log_level, Logger* info_log,
  861. const char* format, va_list ap) {
  862. if (info_log && info_log->GetInfoLogLevel() <= log_level) {
  863. if (log_level == InfoLogLevel::HEADER_LEVEL) {
  864. info_log->LogHeader(format, ap);
  865. } else {
  866. info_log->Logv(log_level, format, ap);
  867. }
  868. }
  869. }
  870. void Log(const InfoLogLevel log_level, Logger* info_log, const char* format,
  871. ...) {
  872. va_list ap;
  873. va_start(ap, format);
  874. Logv(log_level, info_log, format, ap);
  875. va_end(ap);
  876. }
  877. static void Headerv(Logger* info_log, const char* format, va_list ap) {
  878. if (info_log) {
  879. info_log->LogHeader(format, ap);
  880. }
  881. }
  882. void Header(Logger* info_log, const char* format, ...) {
  883. va_list ap;
  884. va_start(ap, format);
  885. Headerv(info_log, format, ap);
  886. va_end(ap);
  887. }
  888. static void Debugv(Logger* info_log, const char* format, va_list ap) {
  889. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::DEBUG_LEVEL) {
  890. info_log->Logv(InfoLogLevel::DEBUG_LEVEL, format, ap);
  891. }
  892. }
  893. void Debug(Logger* info_log, const char* format, ...) {
  894. va_list ap;
  895. va_start(ap, format);
  896. Debugv(info_log, format, ap);
  897. va_end(ap);
  898. }
  899. static void Infov(Logger* info_log, const char* format, va_list ap) {
  900. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::INFO_LEVEL) {
  901. info_log->Logv(InfoLogLevel::INFO_LEVEL, format, ap);
  902. }
  903. }
  904. void Info(Logger* info_log, const char* format, ...) {
  905. va_list ap;
  906. va_start(ap, format);
  907. Infov(info_log, format, ap);
  908. va_end(ap);
  909. }
  910. static void Warnv(Logger* info_log, const char* format, va_list ap) {
  911. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::WARN_LEVEL) {
  912. info_log->Logv(InfoLogLevel::WARN_LEVEL, format, ap);
  913. }
  914. }
  915. void Warn(Logger* info_log, const char* format, ...) {
  916. va_list ap;
  917. va_start(ap, format);
  918. Warnv(info_log, format, ap);
  919. va_end(ap);
  920. }
  921. static void Errorv(Logger* info_log, const char* format, va_list ap) {
  922. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::ERROR_LEVEL) {
  923. info_log->Logv(InfoLogLevel::ERROR_LEVEL, format, ap);
  924. }
  925. }
  926. void Error(Logger* info_log, const char* format, ...) {
  927. va_list ap;
  928. va_start(ap, format);
  929. Errorv(info_log, format, ap);
  930. va_end(ap);
  931. }
  932. static void Fatalv(Logger* info_log, const char* format, va_list ap) {
  933. if (info_log && info_log->GetInfoLogLevel() <= InfoLogLevel::FATAL_LEVEL) {
  934. info_log->Logv(InfoLogLevel::FATAL_LEVEL, format, ap);
  935. }
  936. }
  937. void Fatal(Logger* info_log, const char* format, ...) {
  938. va_list ap;
  939. va_start(ap, format);
  940. Fatalv(info_log, format, ap);
  941. va_end(ap);
  942. }
  943. void LogFlush(const std::shared_ptr<Logger>& info_log) {
  944. LogFlush(info_log.get());
  945. }
  946. void Log(const InfoLogLevel log_level, const std::shared_ptr<Logger>& info_log,
  947. const char* format, ...) {
  948. va_list ap;
  949. va_start(ap, format);
  950. Logv(log_level, info_log.get(), format, ap);
  951. va_end(ap);
  952. }
  953. void Header(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  954. va_list ap;
  955. va_start(ap, format);
  956. Headerv(info_log.get(), format, ap);
  957. va_end(ap);
  958. }
  959. void Debug(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  960. va_list ap;
  961. va_start(ap, format);
  962. Debugv(info_log.get(), format, ap);
  963. va_end(ap);
  964. }
  965. void Info(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  966. va_list ap;
  967. va_start(ap, format);
  968. Infov(info_log.get(), format, ap);
  969. va_end(ap);
  970. }
  971. void Warn(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  972. va_list ap;
  973. va_start(ap, format);
  974. Warnv(info_log.get(), format, ap);
  975. va_end(ap);
  976. }
  977. void Error(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  978. va_list ap;
  979. va_start(ap, format);
  980. Errorv(info_log.get(), format, ap);
  981. va_end(ap);
  982. }
  983. void Fatal(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  984. va_list ap;
  985. va_start(ap, format);
  986. Fatalv(info_log.get(), format, ap);
  987. va_end(ap);
  988. }
  989. void Log(const std::shared_ptr<Logger>& info_log, const char* format, ...) {
  990. va_list ap;
  991. va_start(ap, format);
  992. Logv(info_log.get(), format, ap);
  993. va_end(ap);
  994. }
  995. Status WriteStringToFile(Env* env, const Slice& data, const std::string& fname,
  996. bool should_sync, const IOOptions* io_options) {
  997. const auto& fs = env->GetFileSystem();
  998. return WriteStringToFile(fs.get(), data, fname, should_sync,
  999. io_options ? *io_options : IOOptions());
  1000. }
  1001. Status ReadFileToString(Env* env, const std::string& fname, std::string* data) {
  1002. const auto& fs = env->GetFileSystem();
  1003. return ReadFileToString(fs.get(), fname, data);
  1004. }
  1005. namespace { // anonymous namespace
  1006. void AssignEnvOptions(EnvOptions* env_options, const DBOptions& options) {
  1007. env_options->use_mmap_reads = options.allow_mmap_reads;
  1008. env_options->use_mmap_writes = options.allow_mmap_writes;
  1009. env_options->use_direct_reads = options.use_direct_reads;
  1010. env_options->set_fd_cloexec = options.is_fd_close_on_exec;
  1011. env_options->bytes_per_sync = options.bytes_per_sync;
  1012. env_options->compaction_readahead_size = options.compaction_readahead_size;
  1013. env_options->rate_limiter = options.rate_limiter.get();
  1014. env_options->writable_file_max_buffer_size =
  1015. options.writable_file_max_buffer_size;
  1016. env_options->allow_fallocate = options.allow_fallocate;
  1017. env_options->strict_bytes_per_sync = options.strict_bytes_per_sync;
  1018. options.env->SanitizeEnvOptions(env_options);
  1019. }
  1020. } // namespace
  1021. EnvOptions Env::OptimizeForLogWrite(const EnvOptions& env_options,
  1022. const DBOptions& db_options) const {
  1023. EnvOptions optimized_env_options(env_options);
  1024. optimized_env_options.bytes_per_sync = db_options.wal_bytes_per_sync;
  1025. optimized_env_options.writable_file_max_buffer_size =
  1026. db_options.writable_file_max_buffer_size;
  1027. return optimized_env_options;
  1028. }
  1029. EnvOptions Env::OptimizeForManifestWrite(const EnvOptions& env_options) const {
  1030. return env_options;
  1031. }
  1032. EnvOptions Env::OptimizeForLogRead(const EnvOptions& env_options) const {
  1033. EnvOptions optimized_env_options(env_options);
  1034. optimized_env_options.use_direct_reads = false;
  1035. return optimized_env_options;
  1036. }
  1037. EnvOptions Env::OptimizeForManifestRead(const EnvOptions& env_options) const {
  1038. EnvOptions optimized_env_options(env_options);
  1039. optimized_env_options.use_direct_reads = false;
  1040. return optimized_env_options;
  1041. }
  1042. EnvOptions Env::OptimizeForCompactionTableWrite(
  1043. const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
  1044. EnvOptions optimized_env_options(env_options);
  1045. optimized_env_options.use_direct_writes =
  1046. db_options.use_direct_io_for_flush_and_compaction;
  1047. return optimized_env_options;
  1048. }
  1049. EnvOptions Env::OptimizeForCompactionTableRead(
  1050. const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
  1051. EnvOptions optimized_env_options(env_options);
  1052. optimized_env_options.use_direct_reads = db_options.use_direct_reads;
  1053. return optimized_env_options;
  1054. }
  1055. EnvOptions Env::OptimizeForBlobFileRead(
  1056. const EnvOptions& env_options, const ImmutableDBOptions& db_options) const {
  1057. EnvOptions optimized_env_options(env_options);
  1058. optimized_env_options.use_direct_reads = db_options.use_direct_reads;
  1059. return optimized_env_options;
  1060. }
  1061. EnvOptions::EnvOptions(const DBOptions& options) {
  1062. AssignEnvOptions(this, options);
  1063. }
  1064. EnvOptions::EnvOptions() {
  1065. DBOptions options;
  1066. AssignEnvOptions(this, options);
  1067. }
  1068. Status NewEnvLogger(const std::string& fname, Env* env,
  1069. std::shared_ptr<Logger>* result) {
  1070. FileOptions options;
  1071. // TODO: Tune the buffer size.
  1072. options.writable_file_max_buffer_size = 1024 * 1024;
  1073. std::unique_ptr<FSWritableFile> writable_file;
  1074. const auto status = env->GetFileSystem()->NewWritableFile(
  1075. fname, options, &writable_file, nullptr);
  1076. if (!status.ok()) {
  1077. return status;
  1078. }
  1079. *result = std::make_shared<EnvLogger>(std::move(writable_file), fname,
  1080. options, env);
  1081. return Status::OK();
  1082. }
  1083. const std::shared_ptr<FileSystem>& Env::GetFileSystem() const {
  1084. return file_system_;
  1085. }
  1086. const std::shared_ptr<SystemClock>& Env::GetSystemClock() const {
  1087. return system_clock_;
  1088. }
  1089. namespace {
  1090. static std::unordered_map<std::string, OptionTypeInfo> sc_wrapper_type_info = {
  1091. {"target",
  1092. OptionTypeInfo::AsCustomSharedPtr<SystemClock>(
  1093. 0, OptionVerificationType::kByName, OptionTypeFlags::kDontSerialize)},
  1094. };
  1095. } // namespace
  1096. SystemClockWrapper::SystemClockWrapper(const std::shared_ptr<SystemClock>& t)
  1097. : target_(t) {
  1098. RegisterOptions("", &target_, &sc_wrapper_type_info);
  1099. }
  1100. Status SystemClockWrapper::PrepareOptions(const ConfigOptions& options) {
  1101. if (target_ == nullptr) {
  1102. target_ = SystemClock::Default();
  1103. }
  1104. return SystemClock::PrepareOptions(options);
  1105. }
  1106. std::string SystemClockWrapper::SerializeOptions(
  1107. const ConfigOptions& config_options, const std::string& header) const {
  1108. auto parent = SystemClock::SerializeOptions(config_options, "");
  1109. if (config_options.IsShallow() || target_ == nullptr ||
  1110. target_->IsInstanceOf(SystemClock::kDefaultName())) {
  1111. return parent;
  1112. } else {
  1113. std::string result = header;
  1114. if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
  1115. result.append(OptionTypeInfo::kIdPropName()).append("=");
  1116. }
  1117. result.append(parent);
  1118. if (!EndsWith(result, config_options.delimiter)) {
  1119. result.append(config_options.delimiter);
  1120. }
  1121. result.append("target=").append(target_->ToString(config_options));
  1122. return result;
  1123. }
  1124. }
  1125. static int RegisterBuiltinSystemClocks(ObjectLibrary& library,
  1126. const std::string& /*arg*/) {
  1127. library.AddFactory<SystemClock>(
  1128. EmulatedSystemClock::kClassName(),
  1129. [](const std::string& /*uri*/, std::unique_ptr<SystemClock>* guard,
  1130. std::string* /* errmsg */) {
  1131. guard->reset(new EmulatedSystemClock(SystemClock::Default()));
  1132. return guard->get();
  1133. });
  1134. size_t num_types;
  1135. return static_cast<int>(library.GetFactoryCount(&num_types));
  1136. }
  1137. Status SystemClock::CreateFromString(const ConfigOptions& config_options,
  1138. const std::string& value,
  1139. std::shared_ptr<SystemClock>* result) {
  1140. auto clock = SystemClock::Default();
  1141. if (clock->IsInstanceOf(value)) {
  1142. *result = clock;
  1143. return Status::OK();
  1144. } else {
  1145. static std::once_flag once;
  1146. std::call_once(once, [&]() {
  1147. RegisterBuiltinSystemClocks(*(ObjectLibrary::Default().get()), "");
  1148. });
  1149. return LoadSharedObject<SystemClock>(config_options, value, result);
  1150. }
  1151. }
  1152. bool SystemClock::TimedWait(port::CondVar* cv,
  1153. std::chrono::microseconds deadline) {
  1154. return cv->TimedWait(deadline.count());
  1155. }
  1156. } // namespace ROCKSDB_NAMESPACE