]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/include/rocksdb/utilities/env_mirror.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / include / rocksdb / utilities / env_mirror.h
1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 // Copyright (c) 2015, Red Hat, Inc. All rights reserved.
3 // This source code is licensed under both the GPLv2 (found in the
4 // COPYING file in the root directory) and Apache 2.0 License
5 // (found in the LICENSE.Apache file in the root directory).
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 //
10 // MirrorEnv is an Env implementation that mirrors all file-related
11 // operations to two backing Env's (provided at construction time).
12 // Writes are mirrored. For read operations, we do the read from both
13 // backends and assert that the results match.
14 //
15 // This is useful when implementing a new Env and ensuring that the
16 // semantics and behavior are correct (in that they match that of an
17 // existing, stable Env, like the default POSIX one).
18
19 #pragma once
20
21 #ifndef ROCKSDB_LITE
22
23 #include <algorithm>
24 #include <iostream>
25 #include <vector>
26
27 #include "rocksdb/env.h"
28
29 namespace ROCKSDB_NAMESPACE {
30
31 class SequentialFileMirror;
32 class RandomAccessFileMirror;
33 class WritableFileMirror;
34
35 class EnvMirror : public EnvWrapper {
36 Env *a_, *b_;
37 bool free_a_, free_b_;
38
39 public:
40 EnvMirror(Env* a, Env* b, bool free_a = false, bool free_b = false)
41 : EnvWrapper(a), a_(a), b_(b), free_a_(free_a), free_b_(free_b) {}
42 ~EnvMirror() {
43 if (free_a_) delete a_;
44 if (free_b_) delete b_;
45 }
46
47 Status NewSequentialFile(const std::string& f,
48 std::unique_ptr<SequentialFile>* r,
49 const EnvOptions& options) override;
50 Status NewRandomAccessFile(const std::string& f,
51 std::unique_ptr<RandomAccessFile>* r,
52 const EnvOptions& options) override;
53 Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
54 const EnvOptions& options) override;
55 Status ReuseWritableFile(const std::string& fname,
56 const std::string& old_fname,
57 std::unique_ptr<WritableFile>* r,
58 const EnvOptions& options) override;
59 virtual Status NewDirectory(const std::string& name,
60 std::unique_ptr<Directory>* result) override {
61 std::unique_ptr<Directory> br;
62 Status as = a_->NewDirectory(name, result);
63 Status bs = b_->NewDirectory(name, &br);
64 assert(as == bs);
65 return as;
66 }
67 Status FileExists(const std::string& f) override {
68 Status as = a_->FileExists(f);
69 Status bs = b_->FileExists(f);
70 assert(as == bs);
71 return as;
72 }
73 #if defined(_MSC_VER)
74 #pragma warning(push)
75 // logical operation on address of string constant
76 #pragma warning(disable : 4130)
77 #endif
78 Status GetChildren(const std::string& dir,
79 std::vector<std::string>* r) override {
80 std::vector<std::string> ar, br;
81 Status as = a_->GetChildren(dir, &ar);
82 Status bs = b_->GetChildren(dir, &br);
83 assert(as == bs);
84 std::sort(ar.begin(), ar.end());
85 std::sort(br.begin(), br.end());
86 if (!as.ok() || ar != br) {
87 assert(0 == "getchildren results don't match");
88 }
89 *r = ar;
90 return as;
91 }
92 #if defined(_MSC_VER)
93 #pragma warning(pop)
94 #endif
95 Status DeleteFile(const std::string& f) override {
96 Status as = a_->DeleteFile(f);
97 Status bs = b_->DeleteFile(f);
98 assert(as == bs);
99 return as;
100 }
101 Status CreateDir(const std::string& d) override {
102 Status as = a_->CreateDir(d);
103 Status bs = b_->CreateDir(d);
104 assert(as == bs);
105 return as;
106 }
107 Status CreateDirIfMissing(const std::string& d) override {
108 Status as = a_->CreateDirIfMissing(d);
109 Status bs = b_->CreateDirIfMissing(d);
110 assert(as == bs);
111 return as;
112 }
113 Status DeleteDir(const std::string& d) override {
114 Status as = a_->DeleteDir(d);
115 Status bs = b_->DeleteDir(d);
116 assert(as == bs);
117 return as;
118 }
119 Status GetFileSize(const std::string& f, uint64_t* s) override {
120 uint64_t asize, bsize;
121 Status as = a_->GetFileSize(f, &asize);
122 Status bs = b_->GetFileSize(f, &bsize);
123 assert(as == bs);
124 assert(!as.ok() || asize == bsize);
125 *s = asize;
126 return as;
127 }
128
129 Status GetFileModificationTime(const std::string& fname,
130 uint64_t* file_mtime) override {
131 uint64_t amtime, bmtime;
132 Status as = a_->GetFileModificationTime(fname, &amtime);
133 Status bs = b_->GetFileModificationTime(fname, &bmtime);
134 assert(as == bs);
135 assert(!as.ok() || amtime - bmtime < 10000 || bmtime - amtime < 10000);
136 *file_mtime = amtime;
137 return as;
138 }
139
140 Status RenameFile(const std::string& s, const std::string& t) override {
141 Status as = a_->RenameFile(s, t);
142 Status bs = b_->RenameFile(s, t);
143 assert(as == bs);
144 return as;
145 }
146
147 Status LinkFile(const std::string& s, const std::string& t) override {
148 Status as = a_->LinkFile(s, t);
149 Status bs = b_->LinkFile(s, t);
150 assert(as == bs);
151 return as;
152 }
153
154 class FileLockMirror : public FileLock {
155 public:
156 FileLock *a_, *b_;
157 FileLockMirror(FileLock* a, FileLock* b) : a_(a), b_(b) {}
158 };
159
160 Status LockFile(const std::string& f, FileLock** l) override {
161 FileLock *al, *bl;
162 Status as = a_->LockFile(f, &al);
163 Status bs = b_->LockFile(f, &bl);
164 assert(as == bs);
165 if (as.ok()) *l = new FileLockMirror(al, bl);
166 return as;
167 }
168
169 Status UnlockFile(FileLock* l) override {
170 FileLockMirror* ml = static_cast<FileLockMirror*>(l);
171 Status as = a_->UnlockFile(ml->a_);
172 Status bs = b_->UnlockFile(ml->b_);
173 assert(as == bs);
174 delete ml;
175 return as;
176 }
177 };
178
179 } // namespace ROCKSDB_NAMESPACE
180
181 #endif // ROCKSDB_LITE