YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/util/memenv.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4
//
5
// The following only applies to changes made to this file as part of YugaByte development.
6
//
7
// Portions Copyright (c) YugaByte, Inc.
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
10
// in compliance with the License.  You may obtain a copy of the License at
11
//
12
// http://www.apache.org/licenses/LICENSE-2.0
13
//
14
// Unless required by applicable law or agreed to in writing, software distributed under the License
15
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16
// or implied.  See the License for the specific language governing permissions and limitations
17
// under the License.
18
//
19
#include <string.h>
20
21
#include <map>
22
#include <string>
23
#include <vector>
24
25
#include "yb/rocksdb/env.h"
26
#include "yb/rocksdb/port/port.h"
27
#include "yb/rocksdb/util/mutexlock.h"
28
#include "yb/util/file_system_mem.h"
29
#include "yb/util/status.h"
30
31
namespace rocksdb {
32
33
typedef yb::InMemoryFileState InMemoryFileState;
34
35
#ifndef ROCKSDB_LITE
36
37
namespace {
38
39
94
std::string NormalizeFileName(const std::string fname) {
40
94
  if (fname.find("//") == std::string::npos) {
41
91
    return fname;
42
91
  }
43
3
  std::string out_name = "";
44
3
  bool is_slash = false;
45
67
  for (char c : fname) {
46
67
    if (c == '/' && 
is_slash12
) {
47
3
      continue;
48
3
    }
49
64
    out_name.append(1, c);
50
64
    if (c == '/') {
51
9
      is_slash = true;
52
55
    } else {
53
55
      is_slash = false;
54
55
    }
55
64
  }
56
3
  return out_name;
57
94
}
58
59
class WritableFileImpl : public WritableFile {
60
 public:
61
26
  explicit WritableFileImpl(std::shared_ptr<InMemoryFileState> file) : file_(std::move(file)) {}
62
63
26
  ~WritableFileImpl() {}
64
65
60
  Status Append(const Slice& data) override {
66
60
    return file_->Append(data);
67
60
  }
68
15
  Status Truncate(uint64_t size) override {
69
15
    return Status::OK();
70
15
  }
71
18
  Status Close() override { return Status::OK(); }
72
48
  Status Flush() override { return Status::OK(); }
73
12
  Status Sync() override { return Status::OK(); }
74
75
 private:
76
  std::shared_ptr<InMemoryFileState> file_;
77
};
78
79
class InMemoryDirectory : public Directory {
80
 public:
81
5
  Status Fsync() override { return Status::OK(); }
82
};
83
84
class InMemoryEnv : public EnvWrapper {
85
 public:
86
13
  explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }
87
88
13
  virtual ~InMemoryEnv() {}
89
90
  // Partial implementation of the Env interface.
91
  virtual Status NewSequentialFile(const std::string& fname,
92
                                   unique_ptr<SequentialFile>* result,
93
10
                                   const EnvOptions& soptions) override {
94
10
    std::string nfname = NormalizeFileName(fname);
95
10
    MutexLock lock(&mutex_);
96
10
    if (file_map_.find(fname) == file_map_.end()) {
97
1
      *result = NULL;
98
1
      return STATUS(IOError, fname, "File not found");
99
1
    }
100
101
9
    result->reset(new yb::InMemorySequentialFile(file_map_[nfname]));
102
9
    return Status::OK();
103
10
  }
104
105
  virtual Status NewRandomAccessFile(const std::string& fname,
106
                                     unique_ptr<RandomAccessFile>* result,
107
7
                                     const EnvOptions& soptions) override {
108
7
    std::string nfname = NormalizeFileName(fname);
109
7
    MutexLock lock(&mutex_);
110
7
    if (file_map_.find(nfname) == file_map_.end()) {
111
1
      *result = NULL;
112
1
      return STATUS(IOError, fname, "File not found");
113
1
    }
114
115
6
    result->reset(new yb::InMemoryRandomAccessFile(file_map_[nfname]));
116
6
    return Status::OK();
117
7
  }
118
119
  virtual Status NewWritableFile(const std::string& fname,
120
                                 unique_ptr<WritableFile>* result,
121
26
                                 const EnvOptions& soptions) override {
122
26
    std::string nfname = NormalizeFileName(fname);
123
26
    MutexLock lock(&mutex_);
124
26
    if (file_map_.find(nfname) != file_map_.end()) {
125
1
      DeleteFileInternal(nfname);
126
1
    }
127
128
26
    auto file = std::make_shared<InMemoryFileState>(fname);
129
26
    file_map_[nfname] = file;
130
131
26
    result->reset(new WritableFileImpl(file));
132
26
    return Status::OK();
133
26
  }
134
135
  virtual Status NewDirectory(const std::string& name,
136
2
                              unique_ptr<Directory>* result) override {
137
2
    result->reset(new InMemoryDirectory());
138
2
    return Status::OK();
139
2
  }
140
141
12
  Status FileExists(const std::string& fname) override {
142
12
    std::string nfname = NormalizeFileName(fname);
143
12
    MutexLock lock(&mutex_);
144
12
    if (file_map_.find(nfname) != file_map_.end()) {
145
4
      return Status::OK();
146
8
    } else {
147
8
      return STATUS(NotFound, "");
148
8
    }
149
12
  }
150
151
  virtual Status GetChildren(const std::string& dir,
152
11
                             std::vector<std::string>* result) override {
153
11
    MutexLock lock(&mutex_);
154
11
    result->clear();
155
156
63
    for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); 
++i52
) {
157
52
      const std::string& filename = i->first;
158
159
52
      if (filename.size() >= dir.size() + 1 && filename[dir.size()] == '/' &&
160
52
          Slice(filename).starts_with(Slice(dir))) {
161
52
        result->push_back(filename.substr(dir.size() + 1));
162
52
      }
163
52
    }
164
165
11
    return Status::OK();
166
11
  }
167
168
20
  void DeleteFileInternal(const std::string& fname) {
169
20
    if (file_map_.find(fname) == file_map_.end()) {
170
5
      return;
171
5
    }
172
173
15
    file_map_.erase(fname);
174
15
  }
175
176
13
  Status DeleteFile(const std::string& fname) override {
177
13
    std::string nfname = NormalizeFileName(fname);
178
13
    MutexLock lock(&mutex_);
179
13
    if (file_map_.find(nfname) == file_map_.end()) {
180
1
      return STATUS(IOError, fname, "File not found");
181
1
    }
182
183
12
    DeleteFileInternal(nfname);
184
12
    return Status::OK();
185
13
  }
186
187
6
  Status CreateDir(const std::string& dirname) override {
188
6
    return Status::OK();
189
6
  }
190
191
6
  Status CreateDirIfMissing(const std::string& dirname) override {
192
6
    return Status::OK();
193
6
  }
194
195
1
  Status DeleteDir(const std::string& dirname) override {
196
1
    return Status::OK();
197
1
  }
198
199
  virtual Status GetFileSize(const std::string& fname,
200
10
                             uint64_t* file_size) override {
201
10
    std::string nfname = NormalizeFileName(fname);
202
10
    MutexLock lock(&mutex_);
203
204
10
    if (file_map_.find(nfname) == file_map_.end()) {
205
1
      return STATUS(IOError, fname, "File not found");
206
1
    }
207
208
9
    *file_size = file_map_[nfname]->Size();
209
9
    return Status::OK();
210
10
  }
211
212
  virtual Status GetFileModificationTime(const std::string& fname,
213
0
                                         uint64_t* time) override {
214
0
    return STATUS(NotSupported, "getFileMTime", "Not supported in MemEnv");
215
0
  }
216
217
  virtual Status RenameFile(const std::string& src,
218
8
                            const std::string& dest) override {
219
8
    std::string nsrc = NormalizeFileName(src);
220
8
    std::string ndest = NormalizeFileName(dest);
221
8
    MutexLock lock(&mutex_);
222
8
    if (file_map_.find(nsrc) == file_map_.end()) {
223
1
      return STATUS(IOError, src, "File not found");
224
1
    }
225
226
7
    DeleteFileInternal(dest);
227
7
    file_map_[ndest] = file_map_[nsrc];
228
7
    file_map_.erase(nsrc);
229
7
    return Status::OK();
230
8
  }
231
232
3
  Status LockFile(const std::string& fname, FileLock** lock) override {
233
3
    *lock = new FileLock;
234
3
    return Status::OK();
235
3
  }
236
237
3
  Status UnlockFile(FileLock* lock) override {
238
3
    delete lock;
239
3
    return Status::OK();
240
3
  }
241
242
1
  Status GetTestDirectory(std::string* path) override {
243
1
    *path = "/test";
244
1
    return Status::OK();
245
1
  }
246
247
 private:
248
  // Map from filenames to InMemoryFileState objects, representing a simple file system.
249
  typedef std::map<std::string, std::shared_ptr<InMemoryFileState>> FileSystem;
250
  port::Mutex mutex_;
251
  FileSystem file_map_;  // Protected by mutex_.
252
};
253
254
}  // namespace
255
256
13
Env* NewMemEnv(Env* base_env) {
257
13
  return new InMemoryEnv(base_env);
258
13
}
259
260
#else  // ROCKSDB_LITE
261
262
Env* NewMemEnv(Env* base_env) { return nullptr; }
263
264
#endif  // !ROCKSDB_LITE
265
266
}  // namespace rocksdb