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