1 // Copyright (c) 2013 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.
5 #ifndef THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_
6 #define THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_
12 #include "base/metrics/histogram.h"
13 #include "base/platform_file.h"
14 #include "base/synchronization/condition_variable.h"
15 #include "leveldb/env.h"
16 #include "leveldb/slice.h"
17 #include "leveldb/status.h"
18 #include "port/port_chromium.h"
19 #include "util/mutexlock.h"
21 namespace leveldb_env
{
26 kRandomAccessFileRead
,
48 const char* MethodIDToString(MethodID method
);
50 leveldb::Status
MakeIOError(leveldb::Slice filename
,
54 leveldb::Status
MakeIOError(leveldb::Slice filename
,
57 base::PlatformFileError error
);
58 leveldb::Status
MakeIOError(leveldb::Slice filename
,
62 enum ErrorParsingResult
{
69 ErrorParsingResult
ParseMethodAndError(const char* string
,
72 int GetCorruptionCode(const leveldb::Status
& status
);
73 int GetNumCorruptionCodes();
74 std::string
GetCorruptionMessage(const leveldb::Status
& status
);
75 bool IndicatesDiskFull(const leveldb::Status
& status
);
76 bool IsIOError(const leveldb::Status
& status
);
77 bool IsCorruption(const leveldb::Status
& status
);
78 std::string
FilePathToString(const base::FilePath
& file_path
);
82 virtual void RecordErrorAt(MethodID method
) const = 0;
83 virtual void RecordOSError(MethodID method
, int saved_errno
) const = 0;
84 virtual void RecordOSError(MethodID method
,
85 base::PlatformFileError error
) const = 0;
86 virtual void RecordBackupResult(bool success
) const = 0;
89 class RetrierProvider
{
91 virtual int MaxRetryTimeMillis() const = 0;
92 virtual base::HistogramBase
* GetRetryTimeHistogram(MethodID method
) const = 0;
93 virtual base::HistogramBase
* GetRecoveredFromErrorHistogram(
94 MethodID method
) const = 0;
99 virtual void DidCreateNewFile(const std::string
& fname
) = 0;
100 virtual bool DoesDirNeedSync(const std::string
& fname
) = 0;
101 virtual void DidSyncDir(const std::string
& fname
) = 0;
104 class ChromiumWritableFile
: public leveldb::WritableFile
{
106 ChromiumWritableFile(const std::string
& fname
,
108 const UMALogger
* uma_logger
,
109 WriteTracker
* tracker
,
111 virtual ~ChromiumWritableFile();
112 virtual leveldb::Status
Append(const leveldb::Slice
& data
);
113 virtual leveldb::Status
Close();
114 virtual leveldb::Status
Flush();
115 virtual leveldb::Status
Sync();
123 leveldb::Status
SyncParent();
125 std::string filename_
;
127 const UMALogger
* uma_logger_
;
128 WriteTracker
* tracker_
;
130 std::string parent_dir_
;
134 class ChromiumEnv
: public leveldb::Env
,
136 public RetrierProvider
,
137 public WriteTracker
{
140 virtual ~ChromiumEnv();
142 virtual leveldb::Status
NewSequentialFile(const std::string
& fname
,
143 leveldb::SequentialFile
** result
);
144 virtual leveldb::Status
NewRandomAccessFile(
145 const std::string
& fname
,
146 leveldb::RandomAccessFile
** result
);
147 virtual leveldb::Status
NewWritableFile(const std::string
& fname
,
148 leveldb::WritableFile
** result
);
149 virtual bool FileExists(const std::string
& fname
);
150 virtual leveldb::Status
GetChildren(const std::string
& dir
,
151 std::vector
<std::string
>* result
);
152 virtual leveldb::Status
DeleteFile(const std::string
& fname
);
153 virtual leveldb::Status
CreateDir(const std::string
& name
);
154 virtual leveldb::Status
DeleteDir(const std::string
& name
);
155 virtual leveldb::Status
GetFileSize(const std::string
& fname
, uint64_t* size
);
156 virtual leveldb::Status
RenameFile(const std::string
& src
,
157 const std::string
& dst
);
158 virtual leveldb::Status
LockFile(const std::string
& fname
,
159 leveldb::FileLock
** lock
);
160 virtual leveldb::Status
UnlockFile(leveldb::FileLock
* lock
);
161 virtual void Schedule(void (*function
)(void*), void* arg
);
162 virtual void StartThread(void (*function
)(void* arg
), void* arg
);
163 virtual leveldb::Status
GetTestDirectory(std::string
* path
);
164 virtual leveldb::Status
NewLogger(const std::string
& fname
,
165 leveldb::Logger
** result
);
166 virtual uint64_t NowMicros();
167 virtual void SleepForMicroseconds(int micros
);
170 virtual void DidCreateNewFile(const std::string
& fname
);
171 virtual bool DoesDirNeedSync(const std::string
& fname
);
172 virtual void DidSyncDir(const std::string
& fname
);
178 // File locks may not be exclusive within a process (e.g. on POSIX). Track
179 // locks held by the ChromiumEnv to prevent access within the process.
182 bool Insert(const std::string
& fname
) {
183 leveldb::MutexLock
l(&mu_
);
184 return locked_files_
.insert(fname
).second
;
186 bool Remove(const std::string
& fname
) {
187 leveldb::MutexLock
l(&mu_
);
188 return locked_files_
.erase(fname
) == 1;
191 leveldb::port::Mutex mu_
;
192 std::set
<std::string
> locked_files_
;
195 std::map
<std::string
, bool> needs_sync_map_
;
196 base::Lock map_lock_
;
198 const int kMaxRetryTimeMillis
;
199 // BGThread() is the body of the background thread
201 static void BGThreadWrapper(void* arg
) {
202 reinterpret_cast<ChromiumEnv
*>(arg
)->BGThread();
205 virtual void RecordErrorAt(MethodID method
) const;
206 virtual void RecordOSError(MethodID method
, int saved_errno
) const;
207 virtual void RecordOSError(MethodID method
,
208 base::PlatformFileError error
) const;
209 virtual void RecordBackupResult(bool result
) const;
210 void RestoreIfNecessary(const std::string
& dir
,
211 std::vector
<std::string
>* children
);
212 base::FilePath
RestoreFromBackup(const base::FilePath
& base_name
);
213 void RecordOpenFilesLimit(const std::string
& type
);
214 void RecordLockFileAncestors(int num_missing_ancestors
) const;
215 base::HistogramBase
* GetOSErrorHistogram(MethodID method
, int limit
) const;
216 base::HistogramBase
* GetMethodIOErrorHistogram() const;
217 base::HistogramBase
* GetMaxFDHistogram(const std::string
& type
) const;
218 base::HistogramBase
* GetLockFileAncestorHistogram() const;
220 // RetrierProvider implementation.
221 virtual int MaxRetryTimeMillis() const { return kMaxRetryTimeMillis
; }
222 virtual base::HistogramBase
* GetRetryTimeHistogram(MethodID method
) const;
223 virtual base::HistogramBase
* GetRecoveredFromErrorHistogram(
224 MethodID method
) const;
226 base::FilePath test_directory_
;
229 ::base::ConditionVariable bgsignal_
;
230 bool started_bgthread_
;
232 // Entry per Schedule() call
235 void (*function
)(void*);
237 typedef std::deque
<BGItem
> BGQueue
;
242 } // namespace leveldb_env