34 bool do_delete =
false;
52 Status Read(
uint64_t offset,
size_t n, Slice* result,
char* scratch)
const {
65 size_t block = offset / kBlockSize;
66 size_t block_offset = offset % kBlockSize;
68 if (n <= kBlockSize - block_offset) {
70 *result = Slice(
blocks_[block] + block_offset, n);
74 size_t bytes_to_copy = n;
77 while (bytes_to_copy > 0) {
78 size_t avail = kBlockSize - block_offset;
79 if (avail > bytes_to_copy) {
80 avail = bytes_to_copy;
82 memcpy(dst,
blocks_[block] + block_offset, avail);
84 bytes_to_copy -= avail;
90 *result = Slice(scratch, n);
94 Status Append(
const Slice& data) {
95 const char* src = data.data();
96 size_t src_len = data.size();
100 size_t offset =
size_ % kBlockSize;
104 avail = kBlockSize - offset;
107 blocks_.push_back(
new char[kBlockSize]);
111 if (avail > src_len) {
114 memcpy(
blocks_.back() + offset, src, avail);
126 for (std::vector<char*>::iterator i =
blocks_.begin(); i !=
blocks_.end();
133 FileState(
const FileState&);
134 void operator=(
const FileState&);
145 enum { kBlockSize = 8 * 1024 };
148 class SequentialFileImpl :
public SequentialFile {
150 explicit SequentialFileImpl(FileState* file) :
file_(file),
pos_(0) {
154 ~SequentialFileImpl() {
158 virtual Status Read(
size_t n, Slice* result,
char* scratch) {
159 Status s =
file_->Read(
pos_, n, result, scratch);
161 pos_ += result->size();
170 const size_t available =
file_->Size() -
pos_;
183 class RandomAccessFileImpl :
public RandomAccessFile {
185 explicit RandomAccessFileImpl(FileState* file) :
file_(file) {
189 ~RandomAccessFileImpl() {
193 virtual Status Read(
uint64_t offset,
size_t n, Slice* result,
194 char* scratch)
const {
195 return file_->Read(offset, n, result, scratch);
202 class WritableFileImpl :
public WritableFile {
204 WritableFileImpl(FileState* file) :
file_(file) {
208 ~WritableFileImpl() {
212 virtual Status Append(
const Slice& data) {
213 return file_->Append(data);
216 virtual Status Close() {
return Status::OK(); }
217 virtual Status Flush() {
return Status::OK(); }
218 virtual Status Sync() {
return Status::OK(); }
224 class NoOpLogger :
public Logger {
226 virtual void Logv(
const char* format, va_list ap) { }
229 class InMemoryEnv :
public EnvWrapper {
231 explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }
233 virtual ~InMemoryEnv() {
240 virtual Status NewSequentialFile(
const std::string& fname,
241 SequentialFile** result) {
248 *result =
new SequentialFileImpl(
file_map_[fname]);
252 virtual Status NewRandomAccessFile(
const std::string& fname,
253 RandomAccessFile** result) {
260 *result =
new RandomAccessFileImpl(
file_map_[fname]);
264 virtual Status NewWritableFile(
const std::string& fname,
265 WritableFile** result) {
268 DeleteFileInternal(fname);
271 FileState* file =
new FileState();
275 *result =
new WritableFileImpl(file);
279 virtual bool FileExists(
const std::string& fname) {
284 virtual Status GetChildren(
const std::string& dir,
285 std::vector<std::string>* result) {
290 const std::string& filename = i->first;
292 if (filename.size() >= dir.size() + 1 && filename[dir.size()] ==
'/' &&
293 Slice(filename).starts_with(Slice(dir))) {
294 result->push_back(filename.substr(dir.size() + 1));
301 void DeleteFileInternal(
const std::string& fname) {
310 virtual Status DeleteFile(
const std::string& fname) {
316 DeleteFileInternal(fname);
320 virtual Status CreateDir(
const std::string& dirname) {
324 virtual Status DeleteDir(
const std::string& dirname) {
328 virtual Status GetFileSize(
const std::string& fname,
uint64_t* file_size) {
338 virtual Status RenameFile(
const std::string& src,
339 const std::string& target) {
345 DeleteFileInternal(target);
351 virtual Status LockFile(
const std::string& fname, FileLock** lock) {
352 *lock =
new FileLock;
356 virtual Status UnlockFile(FileLock* lock) {
361 virtual Status GetTestDirectory(std::string* path) {
366 virtual Status NewLogger(
const std::string& fname, Logger** result) {
367 *result =
new NoOpLogger;
373 typedef std::map<std::string, FileState*> FileSystem;
381 return new InMemoryEnv(base_env);
std::vector< char * > blocks_
unsigned long long uint64_t
Env * NewMemEnv(Env *base_env)
static Status IOError(const Slice &msg, const Slice &msg2=Slice())