composite_env_wrapper.h 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  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. #pragma once
  6. #include "rocksdb/env.h"
  7. #include "rocksdb/file_system.h"
  8. namespace ROCKSDB_NAMESPACE {
  9. // The CompositeEnvWrapper class provides an interface that is compatible
  10. // with the old monolithic Env API, and an implementation that wraps around
  11. // the new Env that provides threading and other OS related functionality, and
  12. // the new FileSystem API that provides storage functionality. By
  13. // providing the old Env interface, it allows the rest of RocksDB code to
  14. // be agnostic of whether the underlying Env implementation is a monolithic
  15. // Env or an Env + FileSystem. In the former case, the user will specify
  16. // Options::env only, whereas in the latter case, the user will specify
  17. // Options::env and Options::file_system.
  18. inline IOStatus status_to_io_status(Status&& status) {
  19. if (status.ok()) {
  20. // Fast path
  21. return IOStatus::OK();
  22. } else {
  23. const char* state = status.getState();
  24. if (state) {
  25. return IOStatus(status.code(), status.subcode(),
  26. Slice(state, strlen(status.getState()) + 1),
  27. Slice());
  28. } else {
  29. return IOStatus(status.code(), status.subcode());
  30. }
  31. }
  32. }
  33. class CompositeSequentialFileWrapper : public SequentialFile {
  34. public:
  35. explicit CompositeSequentialFileWrapper(
  36. std::unique_ptr<FSSequentialFile>& target)
  37. : target_(std::move(target)) {}
  38. Status Read(size_t n, Slice* result, char* scratch) override {
  39. IOOptions io_opts;
  40. IODebugContext dbg;
  41. return target_->Read(n, io_opts, result, scratch, &dbg);
  42. }
  43. Status Skip(uint64_t n) override { return target_->Skip(n); }
  44. bool use_direct_io() const override { return target_->use_direct_io(); }
  45. size_t GetRequiredBufferAlignment() const override {
  46. return target_->GetRequiredBufferAlignment();
  47. }
  48. Status InvalidateCache(size_t offset, size_t length) override {
  49. return target_->InvalidateCache(offset, length);
  50. }
  51. Status PositionedRead(uint64_t offset, size_t n, Slice* result,
  52. char* scratch) override {
  53. IOOptions io_opts;
  54. IODebugContext dbg;
  55. return target_->PositionedRead(offset, n, io_opts, result, scratch, &dbg);
  56. }
  57. private:
  58. std::unique_ptr<FSSequentialFile> target_;
  59. };
  60. class CompositeRandomAccessFileWrapper : public RandomAccessFile {
  61. public:
  62. explicit CompositeRandomAccessFileWrapper(
  63. std::unique_ptr<FSRandomAccessFile>& target)
  64. : target_(std::move(target)) {}
  65. Status Read(uint64_t offset, size_t n, Slice* result,
  66. char* scratch) const override {
  67. IOOptions io_opts;
  68. IODebugContext dbg;
  69. return target_->Read(offset, n, io_opts, result, scratch, &dbg);
  70. }
  71. Status MultiRead(ReadRequest* reqs, size_t num_reqs) override {
  72. IOOptions io_opts;
  73. IODebugContext dbg;
  74. std::vector<FSReadRequest> fs_reqs;
  75. Status status;
  76. fs_reqs.resize(num_reqs);
  77. for (size_t i = 0; i < num_reqs; ++i) {
  78. fs_reqs[i].offset = reqs[i].offset;
  79. fs_reqs[i].len = reqs[i].len;
  80. fs_reqs[i].scratch = reqs[i].scratch;
  81. fs_reqs[i].status = IOStatus::OK();
  82. }
  83. status = target_->MultiRead(fs_reqs.data(), num_reqs, io_opts, &dbg);
  84. for (size_t i = 0; i < num_reqs; ++i) {
  85. reqs[i].result = fs_reqs[i].result;
  86. reqs[i].status = fs_reqs[i].status;
  87. }
  88. return status;
  89. }
  90. Status Prefetch(uint64_t offset, size_t n) override {
  91. IOOptions io_opts;
  92. IODebugContext dbg;
  93. return target_->Prefetch(offset, n, io_opts, &dbg);
  94. }
  95. size_t GetUniqueId(char* id, size_t max_size) const override {
  96. return target_->GetUniqueId(id, max_size);
  97. };
  98. void Hint(AccessPattern pattern) override {
  99. target_->Hint((FSRandomAccessFile::AccessPattern)pattern);
  100. }
  101. bool use_direct_io() const override { return target_->use_direct_io(); }
  102. size_t GetRequiredBufferAlignment() const override {
  103. return target_->GetRequiredBufferAlignment();
  104. }
  105. Status InvalidateCache(size_t offset, size_t length) override {
  106. return target_->InvalidateCache(offset, length);
  107. }
  108. private:
  109. std::unique_ptr<FSRandomAccessFile> target_;
  110. };
  111. class CompositeWritableFileWrapper : public WritableFile {
  112. public:
  113. explicit CompositeWritableFileWrapper(std::unique_ptr<FSWritableFile>& t)
  114. : target_(std::move(t)) {}
  115. Status Append(const Slice& data) override {
  116. IOOptions io_opts;
  117. IODebugContext dbg;
  118. return target_->Append(data, io_opts, &dbg);
  119. }
  120. Status PositionedAppend(const Slice& data, uint64_t offset) override {
  121. IOOptions io_opts;
  122. IODebugContext dbg;
  123. return target_->PositionedAppend(data, offset, io_opts, &dbg);
  124. }
  125. Status Truncate(uint64_t size) override {
  126. IOOptions io_opts;
  127. IODebugContext dbg;
  128. return target_->Truncate(size, io_opts, &dbg);
  129. }
  130. Status Close() override {
  131. IOOptions io_opts;
  132. IODebugContext dbg;
  133. return target_->Close(io_opts, &dbg);
  134. }
  135. Status Flush() override {
  136. IOOptions io_opts;
  137. IODebugContext dbg;
  138. return target_->Flush(io_opts, &dbg);
  139. }
  140. Status Sync() override {
  141. IOOptions io_opts;
  142. IODebugContext dbg;
  143. return target_->Sync(io_opts, &dbg);
  144. }
  145. Status Fsync() override {
  146. IOOptions io_opts;
  147. IODebugContext dbg;
  148. return target_->Fsync(io_opts, &dbg);
  149. }
  150. bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
  151. bool use_direct_io() const override { return target_->use_direct_io(); }
  152. size_t GetRequiredBufferAlignment() const override {
  153. return target_->GetRequiredBufferAlignment();
  154. }
  155. void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
  156. target_->SetWriteLifeTimeHint(hint);
  157. }
  158. Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
  159. return target_->GetWriteLifeTimeHint();
  160. }
  161. uint64_t GetFileSize() override {
  162. IOOptions io_opts;
  163. IODebugContext dbg;
  164. return target_->GetFileSize(io_opts, &dbg);
  165. }
  166. void SetPreallocationBlockSize(size_t size) override {
  167. target_->SetPreallocationBlockSize(size);
  168. }
  169. void GetPreallocationStatus(size_t* block_size,
  170. size_t* last_allocated_block) override {
  171. target_->GetPreallocationStatus(block_size, last_allocated_block);
  172. }
  173. size_t GetUniqueId(char* id, size_t max_size) const override {
  174. return target_->GetUniqueId(id, max_size);
  175. }
  176. Status InvalidateCache(size_t offset, size_t length) override {
  177. return target_->InvalidateCache(offset, length);
  178. }
  179. Status RangeSync(uint64_t offset, uint64_t nbytes) override {
  180. IOOptions io_opts;
  181. IODebugContext dbg;
  182. return target_->RangeSync(offset, nbytes, io_opts, &dbg);
  183. }
  184. void PrepareWrite(size_t offset, size_t len) override {
  185. IOOptions io_opts;
  186. IODebugContext dbg;
  187. target_->PrepareWrite(offset, len, io_opts, &dbg);
  188. }
  189. Status Allocate(uint64_t offset, uint64_t len) override {
  190. IOOptions io_opts;
  191. IODebugContext dbg;
  192. return target_->Allocate(offset, len, io_opts, &dbg);
  193. }
  194. std::unique_ptr<FSWritableFile>* target() { return &target_; }
  195. private:
  196. std::unique_ptr<FSWritableFile> target_;
  197. };
  198. class CompositeRandomRWFileWrapper : public RandomRWFile {
  199. public:
  200. explicit CompositeRandomRWFileWrapper(std::unique_ptr<FSRandomRWFile>& target)
  201. : target_(std::move(target)) {}
  202. bool use_direct_io() const override { return target_->use_direct_io(); }
  203. size_t GetRequiredBufferAlignment() const override {
  204. return target_->GetRequiredBufferAlignment();
  205. }
  206. Status Write(uint64_t offset, const Slice& data) override {
  207. IOOptions io_opts;
  208. IODebugContext dbg;
  209. return target_->Write(offset, data, io_opts, &dbg);
  210. }
  211. Status Read(uint64_t offset, size_t n, Slice* result,
  212. char* scratch) const override {
  213. IOOptions io_opts;
  214. IODebugContext dbg;
  215. return target_->Read(offset, n, io_opts, result, scratch, &dbg);
  216. }
  217. Status Flush() override {
  218. IOOptions io_opts;
  219. IODebugContext dbg;
  220. return target_->Flush(io_opts, &dbg);
  221. }
  222. Status Sync() override {
  223. IOOptions io_opts;
  224. IODebugContext dbg;
  225. return target_->Sync(io_opts, &dbg);
  226. }
  227. Status Fsync() override {
  228. IOOptions io_opts;
  229. IODebugContext dbg;
  230. return target_->Fsync(io_opts, &dbg);
  231. }
  232. Status Close() override {
  233. IOOptions io_opts;
  234. IODebugContext dbg;
  235. return target_->Close(io_opts, &dbg);
  236. }
  237. private:
  238. std::unique_ptr<FSRandomRWFile> target_;
  239. };
  240. class CompositeDirectoryWrapper : public Directory {
  241. public:
  242. explicit CompositeDirectoryWrapper(std::unique_ptr<FSDirectory>& target)
  243. : target_(std::move(target)) {}
  244. Status Fsync() override {
  245. IOOptions io_opts;
  246. IODebugContext dbg;
  247. return target_->Fsync(io_opts, &dbg);
  248. }
  249. size_t GetUniqueId(char* id, size_t max_size) const override {
  250. return target_->GetUniqueId(id, max_size);
  251. }
  252. private:
  253. std::unique_ptr<FSDirectory> target_;
  254. };
  255. class CompositeEnvWrapper : public Env {
  256. public:
  257. // Initialize a CompositeEnvWrapper that delegates all thread/time related
  258. // calls to env, and all file operations to fs
  259. explicit CompositeEnvWrapper(Env* env, FileSystem* fs)
  260. : env_target_(env), fs_env_target_(fs) {}
  261. ~CompositeEnvWrapper() {}
  262. // Return the target to which this Env forwards all calls
  263. Env* env_target() const { return env_target_; }
  264. FileSystem* fs_env_target() const { return fs_env_target_; }
  265. // The following text is boilerplate that forwards all methods to target()
  266. Status NewSequentialFile(const std::string& f,
  267. std::unique_ptr<SequentialFile>* r,
  268. const EnvOptions& options) override {
  269. IODebugContext dbg;
  270. std::unique_ptr<FSSequentialFile> file;
  271. Status status;
  272. status =
  273. fs_env_target_->NewSequentialFile(f, FileOptions(options), &file, &dbg);
  274. if (status.ok()) {
  275. r->reset(new CompositeSequentialFileWrapper(file));
  276. }
  277. return status;
  278. }
  279. Status NewRandomAccessFile(const std::string& f,
  280. std::unique_ptr<RandomAccessFile>* r,
  281. const EnvOptions& options) override {
  282. IODebugContext dbg;
  283. std::unique_ptr<FSRandomAccessFile> file;
  284. Status status;
  285. status = fs_env_target_->NewRandomAccessFile(f, FileOptions(options), &file,
  286. &dbg);
  287. if (status.ok()) {
  288. r->reset(new CompositeRandomAccessFileWrapper(file));
  289. }
  290. return status;
  291. }
  292. Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
  293. const EnvOptions& options) override {
  294. IODebugContext dbg;
  295. std::unique_ptr<FSWritableFile> file;
  296. Status status;
  297. status =
  298. fs_env_target_->NewWritableFile(f, FileOptions(options), &file, &dbg);
  299. if (status.ok()) {
  300. r->reset(new CompositeWritableFileWrapper(file));
  301. }
  302. return status;
  303. }
  304. Status ReopenWritableFile(const std::string& fname,
  305. std::unique_ptr<WritableFile>* result,
  306. const EnvOptions& options) override {
  307. IODebugContext dbg;
  308. Status status;
  309. std::unique_ptr<FSWritableFile> file;
  310. status = fs_env_target_->ReopenWritableFile(fname, FileOptions(options),
  311. &file, &dbg);
  312. if (status.ok()) {
  313. result->reset(new CompositeWritableFileWrapper(file));
  314. }
  315. return status;
  316. }
  317. Status ReuseWritableFile(const std::string& fname,
  318. const std::string& old_fname,
  319. std::unique_ptr<WritableFile>* r,
  320. const EnvOptions& options) override {
  321. IODebugContext dbg;
  322. Status status;
  323. std::unique_ptr<FSWritableFile> file;
  324. status = fs_env_target_->ReuseWritableFile(
  325. fname, old_fname, FileOptions(options), &file, &dbg);
  326. if (status.ok()) {
  327. r->reset(new CompositeWritableFileWrapper(file));
  328. }
  329. return status;
  330. }
  331. Status NewRandomRWFile(const std::string& fname,
  332. std::unique_ptr<RandomRWFile>* result,
  333. const EnvOptions& options) override {
  334. IODebugContext dbg;
  335. std::unique_ptr<FSRandomRWFile> file;
  336. Status status;
  337. status = fs_env_target_->NewRandomRWFile(fname, FileOptions(options), &file,
  338. &dbg);
  339. if (status.ok()) {
  340. result->reset(new CompositeRandomRWFileWrapper(file));
  341. }
  342. return status;
  343. }
  344. Status NewMemoryMappedFileBuffer(
  345. const std::string& fname,
  346. std::unique_ptr<MemoryMappedFileBuffer>* result) override {
  347. return fs_env_target_->NewMemoryMappedFileBuffer(fname, result);
  348. }
  349. Status NewDirectory(const std::string& name,
  350. std::unique_ptr<Directory>* result) override {
  351. IOOptions io_opts;
  352. IODebugContext dbg;
  353. std::unique_ptr<FSDirectory> dir;
  354. Status status;
  355. status = fs_env_target_->NewDirectory(name, io_opts, &dir, &dbg);
  356. if (status.ok()) {
  357. result->reset(new CompositeDirectoryWrapper(dir));
  358. }
  359. return status;
  360. }
  361. Status FileExists(const std::string& f) override {
  362. IOOptions io_opts;
  363. IODebugContext dbg;
  364. return fs_env_target_->FileExists(f, io_opts, &dbg);
  365. }
  366. Status GetChildren(const std::string& dir,
  367. std::vector<std::string>* r) override {
  368. IOOptions io_opts;
  369. IODebugContext dbg;
  370. return fs_env_target_->GetChildren(dir, io_opts, r, &dbg);
  371. }
  372. Status GetChildrenFileAttributes(
  373. const std::string& dir, std::vector<FileAttributes>* result) override {
  374. IOOptions io_opts;
  375. IODebugContext dbg;
  376. return fs_env_target_->GetChildrenFileAttributes(dir, io_opts, result,
  377. &dbg);
  378. }
  379. Status DeleteFile(const std::string& f) override {
  380. IOOptions io_opts;
  381. IODebugContext dbg;
  382. return fs_env_target_->DeleteFile(f, io_opts, &dbg);
  383. }
  384. Status Truncate(const std::string& fname, size_t size) override {
  385. IOOptions io_opts;
  386. IODebugContext dbg;
  387. return fs_env_target_->Truncate(fname, size, io_opts, &dbg);
  388. }
  389. Status CreateDir(const std::string& d) override {
  390. IOOptions io_opts;
  391. IODebugContext dbg;
  392. return fs_env_target_->CreateDir(d, io_opts, &dbg);
  393. }
  394. Status CreateDirIfMissing(const std::string& d) override {
  395. IOOptions io_opts;
  396. IODebugContext dbg;
  397. return fs_env_target_->CreateDirIfMissing(d, io_opts, &dbg);
  398. }
  399. Status DeleteDir(const std::string& d) override {
  400. IOOptions io_opts;
  401. IODebugContext dbg;
  402. return fs_env_target_->DeleteDir(d, io_opts, &dbg);
  403. }
  404. Status GetFileSize(const std::string& f, uint64_t* s) override {
  405. IOOptions io_opts;
  406. IODebugContext dbg;
  407. return fs_env_target_->GetFileSize(f, io_opts, s, &dbg);
  408. }
  409. Status GetFileModificationTime(const std::string& fname,
  410. uint64_t* file_mtime) override {
  411. IOOptions io_opts;
  412. IODebugContext dbg;
  413. return fs_env_target_->GetFileModificationTime(fname, io_opts, file_mtime,
  414. &dbg);
  415. }
  416. Status RenameFile(const std::string& s, const std::string& t) override {
  417. IOOptions io_opts;
  418. IODebugContext dbg;
  419. return fs_env_target_->RenameFile(s, t, io_opts, &dbg);
  420. }
  421. Status LinkFile(const std::string& s, const std::string& t) override {
  422. IOOptions io_opts;
  423. IODebugContext dbg;
  424. return fs_env_target_->LinkFile(s, t, io_opts, &dbg);
  425. }
  426. Status NumFileLinks(const std::string& fname, uint64_t* count) override {
  427. IOOptions io_opts;
  428. IODebugContext dbg;
  429. return fs_env_target_->NumFileLinks(fname, io_opts, count, &dbg);
  430. }
  431. Status AreFilesSame(const std::string& first, const std::string& second,
  432. bool* res) override {
  433. IOOptions io_opts;
  434. IODebugContext dbg;
  435. return fs_env_target_->AreFilesSame(first, second, io_opts, res, &dbg);
  436. }
  437. Status LockFile(const std::string& f, FileLock** l) override {
  438. IOOptions io_opts;
  439. IODebugContext dbg;
  440. return fs_env_target_->LockFile(f, io_opts, l, &dbg);
  441. }
  442. Status UnlockFile(FileLock* l) override {
  443. IOOptions io_opts;
  444. IODebugContext dbg;
  445. return fs_env_target_->UnlockFile(l, io_opts, &dbg);
  446. }
  447. Status GetAbsolutePath(const std::string& db_path,
  448. std::string* output_path) override {
  449. IOOptions io_opts;
  450. IODebugContext dbg;
  451. return fs_env_target_->GetAbsolutePath(db_path, io_opts, output_path, &dbg);
  452. }
  453. #if !defined(OS_WIN) && !defined(ROCKSDB_NO_DYNAMIC_EXTENSION)
  454. Status LoadLibrary(const std::string& lib_name,
  455. const std::string& search_path,
  456. std::shared_ptr<DynamicLibrary>* result) override {
  457. return env_target_->LoadLibrary(lib_name, search_path, result);
  458. }
  459. #endif
  460. void Schedule(void (*f)(void* arg), void* a, Priority pri,
  461. void* tag = nullptr, void (*u)(void* arg) = nullptr) override {
  462. return env_target_->Schedule(f, a, pri, tag, u);
  463. }
  464. int UnSchedule(void* tag, Priority pri) override {
  465. return env_target_->UnSchedule(tag, pri);
  466. }
  467. void StartThread(void (*f)(void*), void* a) override {
  468. return env_target_->StartThread(f, a);
  469. }
  470. void WaitForJoin() override { return env_target_->WaitForJoin(); }
  471. unsigned int GetThreadPoolQueueLen(Priority pri = LOW) const override {
  472. return env_target_->GetThreadPoolQueueLen(pri);
  473. }
  474. Status GetTestDirectory(std::string* path) override {
  475. return env_target_->GetTestDirectory(path);
  476. }
  477. Status NewLogger(const std::string& fname,
  478. std::shared_ptr<Logger>* result) override {
  479. return env_target_->NewLogger(fname, result);
  480. }
  481. uint64_t NowMicros() override { return env_target_->NowMicros(); }
  482. uint64_t NowNanos() override { return env_target_->NowNanos(); }
  483. uint64_t NowCPUNanos() override { return env_target_->NowCPUNanos(); }
  484. void SleepForMicroseconds(int micros) override {
  485. env_target_->SleepForMicroseconds(micros);
  486. }
  487. Status GetHostName(char* name, uint64_t len) override {
  488. return env_target_->GetHostName(name, len);
  489. }
  490. Status GetCurrentTime(int64_t* unix_time) override {
  491. return env_target_->GetCurrentTime(unix_time);
  492. }
  493. void SetBackgroundThreads(int num, Priority pri) override {
  494. return env_target_->SetBackgroundThreads(num, pri);
  495. }
  496. int GetBackgroundThreads(Priority pri) override {
  497. return env_target_->GetBackgroundThreads(pri);
  498. }
  499. Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override {
  500. return env_target_->SetAllowNonOwnerAccess(allow_non_owner_access);
  501. }
  502. void IncBackgroundThreadsIfNeeded(int num, Priority pri) override {
  503. return env_target_->IncBackgroundThreadsIfNeeded(num, pri);
  504. }
  505. void LowerThreadPoolIOPriority(Priority pool = LOW) override {
  506. env_target_->LowerThreadPoolIOPriority(pool);
  507. }
  508. void LowerThreadPoolCPUPriority(Priority pool = LOW) override {
  509. env_target_->LowerThreadPoolCPUPriority(pool);
  510. }
  511. std::string TimeToString(uint64_t time) override {
  512. return env_target_->TimeToString(time);
  513. }
  514. Status GetThreadList(std::vector<ThreadStatus>* thread_list) override {
  515. return env_target_->GetThreadList(thread_list);
  516. }
  517. ThreadStatusUpdater* GetThreadStatusUpdater() const override {
  518. return env_target_->GetThreadStatusUpdater();
  519. }
  520. uint64_t GetThreadID() const override { return env_target_->GetThreadID(); }
  521. std::string GenerateUniqueId() override {
  522. return env_target_->GenerateUniqueId();
  523. }
  524. EnvOptions OptimizeForLogRead(const EnvOptions& env_options) const override {
  525. return fs_env_target_->OptimizeForLogRead(FileOptions(env_options));
  526. }
  527. EnvOptions OptimizeForManifestRead(
  528. const EnvOptions& env_options) const override {
  529. return fs_env_target_->OptimizeForManifestRead(
  530. FileOptions(env_options));
  531. }
  532. EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
  533. const DBOptions& db_options) const override {
  534. return fs_env_target_->OptimizeForLogWrite(FileOptions(env_options),
  535. db_options);
  536. }
  537. EnvOptions OptimizeForManifestWrite(
  538. const EnvOptions& env_options) const override {
  539. return fs_env_target_->OptimizeForManifestWrite(
  540. FileOptions(env_options));
  541. }
  542. EnvOptions OptimizeForCompactionTableWrite(
  543. const EnvOptions& env_options,
  544. const ImmutableDBOptions& immutable_ops) const override {
  545. return fs_env_target_->OptimizeForCompactionTableWrite(
  546. FileOptions(env_options),
  547. immutable_ops);
  548. }
  549. EnvOptions OptimizeForCompactionTableRead(
  550. const EnvOptions& env_options,
  551. const ImmutableDBOptions& db_options) const override {
  552. return fs_env_target_->OptimizeForCompactionTableRead(
  553. FileOptions(env_options),
  554. db_options);
  555. }
  556. Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override {
  557. IOOptions io_opts;
  558. IODebugContext dbg;
  559. return fs_env_target_->GetFreeSpace(path, io_opts, diskfree, &dbg);
  560. }
  561. private:
  562. Env* env_target_;
  563. FileSystem* fs_env_target_;
  564. };
  565. class LegacySequentialFileWrapper : public FSSequentialFile {
  566. public:
  567. explicit LegacySequentialFileWrapper(
  568. std::unique_ptr<SequentialFile>&& _target)
  569. : target_(std::move(_target)) {}
  570. IOStatus Read(size_t n, const IOOptions& /*options*/, Slice* result,
  571. char* scratch, IODebugContext* /*dbg*/) override {
  572. return status_to_io_status(target_->Read(n, result, scratch));
  573. }
  574. IOStatus Skip(uint64_t n) override {
  575. return status_to_io_status(target_->Skip(n));
  576. }
  577. bool use_direct_io() const override { return target_->use_direct_io(); }
  578. size_t GetRequiredBufferAlignment() const override {
  579. return target_->GetRequiredBufferAlignment();
  580. }
  581. IOStatus InvalidateCache(size_t offset, size_t length) override {
  582. return status_to_io_status(target_->InvalidateCache(offset, length));
  583. }
  584. IOStatus PositionedRead(uint64_t offset, size_t n,
  585. const IOOptions& /*options*/, Slice* result,
  586. char* scratch, IODebugContext* /*dbg*/) override {
  587. return status_to_io_status(
  588. target_->PositionedRead(offset, n, result, scratch));
  589. }
  590. SequentialFile* target() { return target_.get(); }
  591. private:
  592. std::unique_ptr<SequentialFile> target_;
  593. };
  594. class LegacyRandomAccessFileWrapper : public FSRandomAccessFile {
  595. public:
  596. explicit LegacyRandomAccessFileWrapper(
  597. std::unique_ptr<RandomAccessFile>&& target)
  598. : target_(std::move(target)) {}
  599. IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
  600. Slice* result, char* scratch,
  601. IODebugContext* /*dbg*/) const override {
  602. return status_to_io_status(target_->Read(offset, n, result, scratch));
  603. }
  604. IOStatus MultiRead(FSReadRequest* fs_reqs, size_t num_reqs,
  605. const IOOptions& /*options*/,
  606. IODebugContext* /*dbg*/) override {
  607. std::vector<ReadRequest> reqs;
  608. Status status;
  609. reqs.reserve(num_reqs);
  610. for (size_t i = 0; i < num_reqs; ++i) {
  611. ReadRequest req;
  612. req.offset = fs_reqs[i].offset;
  613. req.len = fs_reqs[i].len;
  614. req.scratch = fs_reqs[i].scratch;
  615. req.status = Status::OK();
  616. reqs.emplace_back(req);
  617. }
  618. status = target_->MultiRead(reqs.data(), num_reqs);
  619. for (size_t i = 0; i < num_reqs; ++i) {
  620. fs_reqs[i].result = reqs[i].result;
  621. fs_reqs[i].status = status_to_io_status(std::move(reqs[i].status));
  622. }
  623. return status_to_io_status(std::move(status));
  624. ;
  625. }
  626. IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& /*options*/,
  627. IODebugContext* /*dbg*/) override {
  628. return status_to_io_status(target_->Prefetch(offset, n));
  629. }
  630. size_t GetUniqueId(char* id, size_t max_size) const override {
  631. return target_->GetUniqueId(id, max_size);
  632. };
  633. void Hint(AccessPattern pattern) override {
  634. target_->Hint((RandomAccessFile::AccessPattern)pattern);
  635. }
  636. bool use_direct_io() const override { return target_->use_direct_io(); }
  637. size_t GetRequiredBufferAlignment() const override {
  638. return target_->GetRequiredBufferAlignment();
  639. }
  640. IOStatus InvalidateCache(size_t offset, size_t length) override {
  641. return status_to_io_status(target_->InvalidateCache(offset, length));
  642. }
  643. private:
  644. std::unique_ptr<RandomAccessFile> target_;
  645. };
  646. class LegacyWritableFileWrapper : public FSWritableFile {
  647. public:
  648. explicit LegacyWritableFileWrapper(std::unique_ptr<WritableFile>&& _target)
  649. : target_(std::move(_target)) {}
  650. IOStatus Append(const Slice& data, const IOOptions& /*options*/,
  651. IODebugContext* /*dbg*/) override {
  652. return status_to_io_status(target_->Append(data));
  653. }
  654. IOStatus PositionedAppend(const Slice& data, uint64_t offset,
  655. const IOOptions& /*options*/,
  656. IODebugContext* /*dbg*/) override {
  657. return status_to_io_status(target_->PositionedAppend(data, offset));
  658. }
  659. IOStatus Truncate(uint64_t size, const IOOptions& /*options*/,
  660. IODebugContext* /*dbg*/) override {
  661. return status_to_io_status(target_->Truncate(size));
  662. }
  663. IOStatus Close(const IOOptions& /*options*/,
  664. IODebugContext* /*dbg*/) override {
  665. return status_to_io_status(target_->Close());
  666. }
  667. IOStatus Flush(const IOOptions& /*options*/,
  668. IODebugContext* /*dbg*/) override {
  669. return status_to_io_status(target_->Flush());
  670. }
  671. IOStatus Sync(const IOOptions& /*options*/,
  672. IODebugContext* /*dbg*/) override {
  673. return status_to_io_status(target_->Sync());
  674. }
  675. IOStatus Fsync(const IOOptions& /*options*/,
  676. IODebugContext* /*dbg*/) override {
  677. return status_to_io_status(target_->Fsync());
  678. }
  679. bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
  680. bool use_direct_io() const override { return target_->use_direct_io(); }
  681. size_t GetRequiredBufferAlignment() const override {
  682. return target_->GetRequiredBufferAlignment();
  683. }
  684. void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
  685. target_->SetWriteLifeTimeHint(hint);
  686. }
  687. Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
  688. return target_->GetWriteLifeTimeHint();
  689. }
  690. uint64_t GetFileSize(const IOOptions& /*options*/,
  691. IODebugContext* /*dbg*/) override {
  692. return target_->GetFileSize();
  693. }
  694. void SetPreallocationBlockSize(size_t size) override {
  695. target_->SetPreallocationBlockSize(size);
  696. }
  697. void GetPreallocationStatus(size_t* block_size,
  698. size_t* last_allocated_block) override {
  699. target_->GetPreallocationStatus(block_size, last_allocated_block);
  700. }
  701. size_t GetUniqueId(char* id, size_t max_size) const override {
  702. return target_->GetUniqueId(id, max_size);
  703. }
  704. IOStatus InvalidateCache(size_t offset, size_t length) override {
  705. return status_to_io_status(target_->InvalidateCache(offset, length));
  706. }
  707. IOStatus RangeSync(uint64_t offset, uint64_t nbytes,
  708. const IOOptions& /*options*/,
  709. IODebugContext* /*dbg*/) override {
  710. return status_to_io_status(target_->RangeSync(offset, nbytes));
  711. }
  712. void PrepareWrite(size_t offset, size_t len, const IOOptions& /*options*/,
  713. IODebugContext* /*dbg*/) override {
  714. target_->PrepareWrite(offset, len);
  715. }
  716. IOStatus Allocate(uint64_t offset, uint64_t len, const IOOptions& /*options*/,
  717. IODebugContext* /*dbg*/) override {
  718. return status_to_io_status(target_->Allocate(offset, len));
  719. }
  720. WritableFile* target() { return target_.get(); }
  721. private:
  722. std::unique_ptr<WritableFile> target_;
  723. };
  724. class LegacyRandomRWFileWrapper : public FSRandomRWFile {
  725. public:
  726. explicit LegacyRandomRWFileWrapper(std::unique_ptr<RandomRWFile>&& target)
  727. : target_(std::move(target)) {}
  728. bool use_direct_io() const override { return target_->use_direct_io(); }
  729. size_t GetRequiredBufferAlignment() const override {
  730. return target_->GetRequiredBufferAlignment();
  731. }
  732. IOStatus Write(uint64_t offset, const Slice& data,
  733. const IOOptions& /*options*/,
  734. IODebugContext* /*dbg*/) override {
  735. return status_to_io_status(target_->Write(offset, data));
  736. }
  737. IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
  738. Slice* result, char* scratch,
  739. IODebugContext* /*dbg*/) const override {
  740. return status_to_io_status(target_->Read(offset, n, result, scratch));
  741. }
  742. IOStatus Flush(const IOOptions& /*options*/,
  743. IODebugContext* /*dbg*/) override {
  744. return status_to_io_status(target_->Flush());
  745. }
  746. IOStatus Sync(const IOOptions& /*options*/,
  747. IODebugContext* /*dbg*/) override {
  748. return status_to_io_status(target_->Sync());
  749. }
  750. IOStatus Fsync(const IOOptions& /*options*/,
  751. IODebugContext* /*dbg*/) override {
  752. return status_to_io_status(target_->Fsync());
  753. }
  754. IOStatus Close(const IOOptions& /*options*/,
  755. IODebugContext* /*dbg*/) override {
  756. return status_to_io_status(target_->Close());
  757. }
  758. private:
  759. std::unique_ptr<RandomRWFile> target_;
  760. };
  761. class LegacyDirectoryWrapper : public FSDirectory {
  762. public:
  763. explicit LegacyDirectoryWrapper(std::unique_ptr<Directory>&& target)
  764. : target_(std::move(target)) {}
  765. IOStatus Fsync(const IOOptions& /*options*/,
  766. IODebugContext* /*dbg*/) override {
  767. return status_to_io_status(target_->Fsync());
  768. }
  769. size_t GetUniqueId(char* id, size_t max_size) const override {
  770. return target_->GetUniqueId(id, max_size);
  771. }
  772. private:
  773. std::unique_ptr<Directory> target_;
  774. };
  775. class LegacyFileSystemWrapper : public FileSystem {
  776. public:
  777. // Initialize an EnvWrapper that delegates all calls to *t
  778. explicit LegacyFileSystemWrapper(Env* t) : target_(t) {}
  779. ~LegacyFileSystemWrapper() override {}
  780. const char* Name() const override { return "Legacy File System"; }
  781. // Return the target to which this Env forwards all calls
  782. Env* target() const { return target_; }
  783. // The following text is boilerplate that forwards all methods to target()
  784. IOStatus NewSequentialFile(const std::string& f,
  785. const FileOptions& file_opts,
  786. std::unique_ptr<FSSequentialFile>* r,
  787. IODebugContext* /*dbg*/) override {
  788. std::unique_ptr<SequentialFile> file;
  789. Status s = target_->NewSequentialFile(f, &file, file_opts);
  790. if (s.ok()) {
  791. r->reset(new LegacySequentialFileWrapper(std::move(file)));
  792. }
  793. return status_to_io_status(std::move(s));
  794. }
  795. IOStatus NewRandomAccessFile(const std::string& f,
  796. const FileOptions& file_opts,
  797. std::unique_ptr<FSRandomAccessFile>* r,
  798. IODebugContext* /*dbg*/) override {
  799. std::unique_ptr<RandomAccessFile> file;
  800. Status s = target_->NewRandomAccessFile(f, &file, file_opts);
  801. if (s.ok()) {
  802. r->reset(new LegacyRandomAccessFileWrapper(std::move(file)));
  803. }
  804. return status_to_io_status(std::move(s));
  805. }
  806. IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
  807. std::unique_ptr<FSWritableFile>* r,
  808. IODebugContext* /*dbg*/) override {
  809. std::unique_ptr<WritableFile> file;
  810. Status s = target_->NewWritableFile(f, &file, file_opts);
  811. if (s.ok()) {
  812. r->reset(new LegacyWritableFileWrapper(std::move(file)));
  813. }
  814. return status_to_io_status(std::move(s));
  815. }
  816. IOStatus ReopenWritableFile(const std::string& fname,
  817. const FileOptions& file_opts,
  818. std::unique_ptr<FSWritableFile>* result,
  819. IODebugContext* /*dbg*/) override {
  820. std::unique_ptr<WritableFile> file;
  821. Status s = target_->ReopenWritableFile(fname, &file, file_opts);
  822. if (s.ok()) {
  823. result->reset(new LegacyWritableFileWrapper(std::move(file)));
  824. }
  825. return status_to_io_status(std::move(s));
  826. }
  827. IOStatus ReuseWritableFile(const std::string& fname,
  828. const std::string& old_fname,
  829. const FileOptions& file_opts,
  830. std::unique_ptr<FSWritableFile>* r,
  831. IODebugContext* /*dbg*/) override {
  832. std::unique_ptr<WritableFile> file;
  833. Status s = target_->ReuseWritableFile(fname, old_fname, &file, file_opts);
  834. if (s.ok()) {
  835. r->reset(new LegacyWritableFileWrapper(std::move(file)));
  836. }
  837. return status_to_io_status(std::move(s));
  838. }
  839. IOStatus NewRandomRWFile(const std::string& fname,
  840. const FileOptions& file_opts,
  841. std::unique_ptr<FSRandomRWFile>* result,
  842. IODebugContext* /*dbg*/) override {
  843. std::unique_ptr<RandomRWFile> file;
  844. Status s = target_->NewRandomRWFile(fname, &file, file_opts);
  845. if (s.ok()) {
  846. result->reset(new LegacyRandomRWFileWrapper(std::move(file)));
  847. }
  848. return status_to_io_status(std::move(s));
  849. }
  850. IOStatus NewMemoryMappedFileBuffer(
  851. const std::string& fname,
  852. std::unique_ptr<MemoryMappedFileBuffer>* result) override {
  853. return status_to_io_status(
  854. target_->NewMemoryMappedFileBuffer(fname, result));
  855. }
  856. IOStatus NewDirectory(const std::string& name, const IOOptions& /*io_opts*/,
  857. std::unique_ptr<FSDirectory>* result,
  858. IODebugContext* /*dbg*/) override {
  859. std::unique_ptr<Directory> dir;
  860. Status s = target_->NewDirectory(name, &dir);
  861. if (s.ok()) {
  862. result->reset(new LegacyDirectoryWrapper(std::move(dir)));
  863. }
  864. return status_to_io_status(std::move(s));
  865. }
  866. IOStatus FileExists(const std::string& f, const IOOptions& /*io_opts*/,
  867. IODebugContext* /*dbg*/) override {
  868. return status_to_io_status(target_->FileExists(f));
  869. }
  870. IOStatus GetChildren(const std::string& dir, const IOOptions& /*io_opts*/,
  871. std::vector<std::string>* r,
  872. IODebugContext* /*dbg*/) override {
  873. return status_to_io_status(target_->GetChildren(dir, r));
  874. }
  875. IOStatus GetChildrenFileAttributes(const std::string& dir,
  876. const IOOptions& /*options*/,
  877. std::vector<FileAttributes>* result,
  878. IODebugContext* /*dbg*/) override {
  879. return status_to_io_status(target_->GetChildrenFileAttributes(dir, result));
  880. }
  881. IOStatus DeleteFile(const std::string& f, const IOOptions& /*options*/,
  882. IODebugContext* /*dbg*/) override {
  883. return status_to_io_status(target_->DeleteFile(f));
  884. }
  885. IOStatus Truncate(const std::string& fname, size_t size,
  886. const IOOptions& /*options*/,
  887. IODebugContext* /*dbg*/) override {
  888. return status_to_io_status(target_->Truncate(fname, size));
  889. }
  890. IOStatus CreateDir(const std::string& d, const IOOptions& /*options*/,
  891. IODebugContext* /*dbg*/) override {
  892. return status_to_io_status(target_->CreateDir(d));
  893. }
  894. IOStatus CreateDirIfMissing(const std::string& d,
  895. const IOOptions& /*options*/,
  896. IODebugContext* /*dbg*/) override {
  897. return status_to_io_status(target_->CreateDirIfMissing(d));
  898. }
  899. IOStatus DeleteDir(const std::string& d, const IOOptions& /*options*/,
  900. IODebugContext* /*dbg*/) override {
  901. return status_to_io_status(target_->DeleteDir(d));
  902. }
  903. IOStatus GetFileSize(const std::string& f, const IOOptions& /*options*/,
  904. uint64_t* s, IODebugContext* /*dbg*/) override {
  905. return status_to_io_status(target_->GetFileSize(f, s));
  906. }
  907. IOStatus GetFileModificationTime(const std::string& fname,
  908. const IOOptions& /*options*/,
  909. uint64_t* file_mtime,
  910. IODebugContext* /*dbg*/) override {
  911. return status_to_io_status(
  912. target_->GetFileModificationTime(fname, file_mtime));
  913. }
  914. IOStatus GetAbsolutePath(const std::string& db_path,
  915. const IOOptions& /*options*/,
  916. std::string* output_path,
  917. IODebugContext* /*dbg*/) override {
  918. return status_to_io_status(target_->GetAbsolutePath(db_path, output_path));
  919. }
  920. IOStatus RenameFile(const std::string& s, const std::string& t,
  921. const IOOptions& /*options*/,
  922. IODebugContext* /*dbg*/) override {
  923. return status_to_io_status(target_->RenameFile(s, t));
  924. }
  925. IOStatus LinkFile(const std::string& s, const std::string& t,
  926. const IOOptions& /*options*/,
  927. IODebugContext* /*dbg*/) override {
  928. return status_to_io_status(target_->LinkFile(s, t));
  929. }
  930. IOStatus NumFileLinks(const std::string& fname, const IOOptions& /*options*/,
  931. uint64_t* count, IODebugContext* /*dbg*/) override {
  932. return status_to_io_status(target_->NumFileLinks(fname, count));
  933. }
  934. IOStatus AreFilesSame(const std::string& first, const std::string& second,
  935. const IOOptions& /*options*/, bool* res,
  936. IODebugContext* /*dbg*/) override {
  937. return status_to_io_status(target_->AreFilesSame(first, second, res));
  938. }
  939. IOStatus LockFile(const std::string& f, const IOOptions& /*options*/,
  940. FileLock** l, IODebugContext* /*dbg*/) override {
  941. return status_to_io_status(target_->LockFile(f, l));
  942. }
  943. IOStatus UnlockFile(FileLock* l, const IOOptions& /*options*/,
  944. IODebugContext* /*dbg*/) override {
  945. return status_to_io_status(target_->UnlockFile(l));
  946. }
  947. IOStatus GetTestDirectory(const IOOptions& /*options*/, std::string* path,
  948. IODebugContext* /*dbg*/) override {
  949. return status_to_io_status(target_->GetTestDirectory(path));
  950. }
  951. IOStatus NewLogger(const std::string& fname, const IOOptions& /*options*/,
  952. std::shared_ptr<Logger>* result,
  953. IODebugContext* /*dbg*/) override {
  954. return status_to_io_status(target_->NewLogger(fname, result));
  955. }
  956. FileOptions OptimizeForLogRead(
  957. const FileOptions& file_options) const override {
  958. return target_->OptimizeForLogRead(file_options);
  959. }
  960. FileOptions OptimizeForManifestRead(
  961. const FileOptions& file_options) const override {
  962. return target_->OptimizeForManifestRead(file_options);
  963. }
  964. FileOptions OptimizeForLogWrite(const FileOptions& file_options,
  965. const DBOptions& db_options) const override {
  966. return target_->OptimizeForLogWrite(file_options, db_options);
  967. }
  968. FileOptions OptimizeForManifestWrite(
  969. const FileOptions& file_options) const override {
  970. return target_->OptimizeForManifestWrite(file_options);
  971. }
  972. FileOptions OptimizeForCompactionTableWrite(
  973. const FileOptions& file_options,
  974. const ImmutableDBOptions& immutable_ops) const override {
  975. return target_->OptimizeForCompactionTableWrite(file_options,
  976. immutable_ops);
  977. }
  978. FileOptions OptimizeForCompactionTableRead(
  979. const FileOptions& file_options,
  980. const ImmutableDBOptions& db_options) const override {
  981. return target_->OptimizeForCompactionTableRead(file_options, db_options);
  982. }
  983. IOStatus GetFreeSpace(const std::string& path, const IOOptions& /*options*/,
  984. uint64_t* diskfree, IODebugContext* /*dbg*/) override {
  985. return status_to_io_status(target_->GetFreeSpace(path, diskfree));
  986. }
  987. private:
  988. Env* target_;
  989. };
  990. inline std::unique_ptr<FSSequentialFile> NewLegacySequentialFileWrapper(
  991. std::unique_ptr<SequentialFile>& file) {
  992. return std::unique_ptr<FSSequentialFile>(
  993. new LegacySequentialFileWrapper(std::move(file)));
  994. }
  995. inline std::unique_ptr<FSRandomAccessFile> NewLegacyRandomAccessFileWrapper(
  996. std::unique_ptr<RandomAccessFile>& file) {
  997. return std::unique_ptr<FSRandomAccessFile>(
  998. new LegacyRandomAccessFileWrapper(std::move(file)));
  999. }
  1000. inline std::unique_ptr<FSWritableFile> NewLegacyWritableFileWrapper(
  1001. std::unique_ptr<WritableFile>&& file) {
  1002. return std::unique_ptr<FSWritableFile>(
  1003. new LegacyWritableFileWrapper(std::move(file)));
  1004. }
  1005. } // namespace ROCKSDB_NAMESPACE