]>
Commit | Line | Data |
---|---|---|
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 | #include "file/file_util.h" | |
7 | ||
8 | #include <string> | |
9 | #include <algorithm> | |
10 | ||
11 | #include "file/random_access_file_reader.h" | |
12 | #include "file/sequence_file_reader.h" | |
13 | #include "file/sst_file_manager_impl.h" | |
14 | #include "file/writable_file_writer.h" | |
15 | #include "rocksdb/env.h" | |
16 | ||
17 | namespace ROCKSDB_NAMESPACE { | |
18 | ||
19 | // Utility function to copy a file up to a specified length | |
20 | Status CopyFile(FileSystem* fs, const std::string& source, | |
21 | const std::string& destination, uint64_t size, bool use_fsync) { | |
22 | const FileOptions soptions; | |
23 | Status s; | |
24 | std::unique_ptr<SequentialFileReader> src_reader; | |
25 | std::unique_ptr<WritableFileWriter> dest_writer; | |
26 | ||
27 | { | |
28 | std::unique_ptr<FSSequentialFile> srcfile; | |
29 | s = fs->NewSequentialFile(source, soptions, &srcfile, nullptr); | |
30 | if (!s.ok()) { | |
31 | return s; | |
32 | } | |
33 | std::unique_ptr<FSWritableFile> destfile; | |
34 | s = fs->NewWritableFile(destination, soptions, &destfile, nullptr); | |
35 | if (!s.ok()) { | |
36 | return s; | |
37 | } | |
38 | ||
39 | if (size == 0) { | |
40 | // default argument means copy everything | |
41 | s = fs->GetFileSize(source, IOOptions(), &size, nullptr); | |
42 | if (!s.ok()) { | |
43 | return s; | |
44 | } | |
45 | } | |
46 | src_reader.reset(new SequentialFileReader(std::move(srcfile), source)); | |
47 | dest_writer.reset( | |
48 | new WritableFileWriter(std::move(destfile), destination, soptions)); | |
49 | } | |
50 | ||
51 | char buffer[4096]; | |
52 | Slice slice; | |
53 | while (size > 0) { | |
54 | size_t bytes_to_read = std::min(sizeof(buffer), static_cast<size_t>(size)); | |
55 | s = src_reader->Read(bytes_to_read, &slice, buffer); | |
56 | if (!s.ok()) { | |
57 | return s; | |
58 | } | |
59 | if (slice.size() == 0) { | |
60 | return Status::Corruption("file too small"); | |
61 | } | |
62 | s = dest_writer->Append(slice); | |
63 | if (!s.ok()) { | |
64 | return s; | |
65 | } | |
66 | size -= slice.size(); | |
67 | } | |
68 | return dest_writer->Sync(use_fsync); | |
69 | } | |
70 | ||
71 | // Utility function to create a file with the provided contents | |
72 | Status CreateFile(FileSystem* fs, const std::string& destination, | |
73 | const std::string& contents, bool use_fsync) { | |
74 | const EnvOptions soptions; | |
75 | Status s; | |
76 | std::unique_ptr<WritableFileWriter> dest_writer; | |
77 | ||
78 | std::unique_ptr<FSWritableFile> destfile; | |
79 | s = fs->NewWritableFile(destination, soptions, &destfile, nullptr); | |
80 | if (!s.ok()) { | |
81 | return s; | |
82 | } | |
83 | dest_writer.reset( | |
84 | new WritableFileWriter(std::move(destfile), destination, soptions)); | |
85 | s = dest_writer->Append(Slice(contents)); | |
86 | if (!s.ok()) { | |
87 | return s; | |
88 | } | |
89 | return dest_writer->Sync(use_fsync); | |
90 | } | |
91 | ||
92 | Status DeleteDBFile(const ImmutableDBOptions* db_options, | |
93 | const std::string& fname, const std::string& dir_to_sync, | |
94 | const bool force_bg, const bool force_fg) { | |
95 | #ifndef ROCKSDB_LITE | |
96 | SstFileManagerImpl* sfm = | |
97 | static_cast<SstFileManagerImpl*>(db_options->sst_file_manager.get()); | |
98 | if (sfm && !force_fg) { | |
99 | return sfm->ScheduleFileDeletion(fname, dir_to_sync, force_bg); | |
100 | } else { | |
101 | return db_options->env->DeleteFile(fname); | |
102 | } | |
103 | #else | |
104 | (void)dir_to_sync; | |
105 | (void)force_bg; | |
106 | (void)force_fg; | |
107 | // SstFileManager is not supported in ROCKSDB_LITE | |
108 | // Delete file immediately | |
109 | return db_options->env->DeleteFile(fname); | |
110 | #endif | |
111 | } | |
112 | ||
113 | bool IsWalDirSameAsDBPath(const ImmutableDBOptions* db_options) { | |
114 | bool same = false; | |
115 | assert(!db_options->db_paths.empty()); | |
116 | Status s = db_options->env->AreFilesSame(db_options->wal_dir, | |
117 | db_options->db_paths[0].path, &same); | |
118 | if (s.IsNotSupported()) { | |
119 | same = db_options->wal_dir == db_options->db_paths[0].path; | |
120 | } | |
121 | return same; | |
122 | } | |
123 | ||
124 | } // namespace ROCKSDB_NAMESPACE |