Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: third_party/leveldatabase/env_chromium.cc

Issue 1022983004: leveldb: Env no longer implicitly syncs dir for all newly created files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 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 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. 3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 4
5 #include "third_party/leveldatabase/env_chromium.h" 5 #include "third_party/leveldatabase/env_chromium.h"
6 6
7 #if defined(OS_POSIX) 7 #if defined(OS_POSIX)
8 #include <dirent.h> 8 #include <dirent.h>
9 #include <sys/types.h> 9 #include <sys/types.h>
10 #endif 10 #endif
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 std::string filename_; 209 std::string filename_;
210 mutable base::File file_; 210 mutable base::File file_;
211 const UMALogger* uma_logger_; 211 const UMALogger* uma_logger_;
212 }; 212 };
213 213
214 class ChromiumWritableFile : public leveldb::WritableFile { 214 class ChromiumWritableFile : public leveldb::WritableFile {
215 public: 215 public:
216 ChromiumWritableFile(const std::string& fname, 216 ChromiumWritableFile(const std::string& fname,
217 base::File* f, 217 base::File* f,
218 const UMALogger* uma_logger, 218 const UMALogger* uma_logger,
219 WriteTracker* tracker,
220 bool make_backup); 219 bool make_backup);
221 virtual ~ChromiumWritableFile() {} 220 virtual ~ChromiumWritableFile() {}
222 leveldb::Status Append(const leveldb::Slice& data) override; 221 leveldb::Status Append(const leveldb::Slice& data) override;
223 leveldb::Status Close() override; 222 leveldb::Status Close() override;
224 leveldb::Status Flush() override; 223 leveldb::Status Flush() override;
225 leveldb::Status Sync() override; 224 leveldb::Status Sync() override;
226 225
227 private: 226 private:
228 enum Type { kManifest, kTable, kOther }; 227 enum Type { kManifest, kTable, kOther };
229 leveldb::Status SyncParent(); 228 leveldb::Status SyncParent();
230 229
231 std::string filename_; 230 std::string filename_;
232 scoped_ptr<base::File> file_; 231 scoped_ptr<base::File> file_;
233 const UMALogger* uma_logger_; 232 const UMALogger* uma_logger_;
234 WriteTracker* tracker_;
235 Type file_type_; 233 Type file_type_;
236 std::string parent_dir_; 234 std::string parent_dir_;
237 bool make_backup_; 235 bool make_backup_;
238 }; 236 };
239 237
240 ChromiumWritableFile::ChromiumWritableFile(const std::string& fname, 238 ChromiumWritableFile::ChromiumWritableFile(const std::string& fname,
241 base::File* f, 239 base::File* f,
242 const UMALogger* uma_logger, 240 const UMALogger* uma_logger,
243 WriteTracker* tracker,
244 bool make_backup) 241 bool make_backup)
245 : filename_(fname), 242 : filename_(fname),
246 file_(f), 243 file_(f),
247 uma_logger_(uma_logger), 244 uma_logger_(uma_logger),
248 tracker_(tracker),
249 file_type_(kOther), 245 file_type_(kOther),
250 make_backup_(make_backup) { 246 make_backup_(make_backup) {
251 FilePath path = FilePath::FromUTF8Unsafe(fname); 247 FilePath path = FilePath::FromUTF8Unsafe(fname);
252 if (path.BaseName().AsUTF8Unsafe().find("MANIFEST") == 0) 248 if (path.BaseName().AsUTF8Unsafe().find("MANIFEST") == 0)
253 file_type_ = kManifest; 249 file_type_ = kManifest;
254 else if (path.MatchesExtension(table_extension)) 250 else if (path.MatchesExtension(table_extension))
255 file_type_ = kTable; 251 file_type_ = kTable;
256 if (file_type_ != kManifest)
257 tracker_->DidCreateNewFile(filename_);
258 parent_dir_ = FilePath::FromUTF8Unsafe(fname).DirName().AsUTF8Unsafe(); 252 parent_dir_ = FilePath::FromUTF8Unsafe(fname).DirName().AsUTF8Unsafe();
259 } 253 }
260 254
261 Status ChromiumWritableFile::SyncParent() { 255 Status ChromiumWritableFile::SyncParent() {
262 TRACE_EVENT0("leveldb", "SyncParent"); 256 TRACE_EVENT0("leveldb", "SyncParent");
263 #if defined(OS_POSIX) 257 #if defined(OS_POSIX)
264 FilePath path = FilePath::FromUTF8Unsafe(parent_dir_); 258 FilePath path = FilePath::FromUTF8Unsafe(parent_dir_);
265 base::File f(path, base::File::FLAG_OPEN | base::File::FLAG_READ); 259 base::File f(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
266 if (!f.IsValid()) { 260 if (!f.IsValid()) {
267 return MakeIOError(parent_dir_, "Unable to open directory", kSyncParent, 261 return MakeIOError(parent_dir_, "Unable to open directory", kSyncParent,
268 f.error_details()); 262 f.error_details());
269 } 263 }
270 if (!f.Flush()) { 264 if (!f.Flush()) {
271 base::File::Error error = LastFileError(); 265 base::File::Error error = LastFileError();
272 return MakeIOError(parent_dir_, base::File::ErrorToString(error), 266 return MakeIOError(parent_dir_, base::File::ErrorToString(error),
273 kSyncParent, error); 267 kSyncParent, error);
274 } 268 }
275 #endif 269 #endif
276 return Status::OK(); 270 return Status::OK();
277 } 271 }
278 272
279 Status ChromiumWritableFile::Append(const Slice& data) { 273 Status ChromiumWritableFile::Append(const Slice& data) {
280 if (file_type_ == kManifest && tracker_->DoesDirNeedSync(filename_)) {
281 Status s = SyncParent();
282 if (!s.ok())
283 return s;
284 tracker_->DidSyncDir(filename_);
285 }
286
287 int bytes_written = file_->WriteAtCurrentPos(data.data(), data.size()); 274 int bytes_written = file_->WriteAtCurrentPos(data.data(), data.size());
288 if (bytes_written != data.size()) { 275 if (bytes_written != data.size()) {
289 base::File::Error error = LastFileError(); 276 base::File::Error error = LastFileError();
290 uma_logger_->RecordOSError(kWritableFileAppend, error); 277 uma_logger_->RecordOSError(kWritableFileAppend, error);
291 return MakeIOError(filename_, base::File::ErrorToString(error), 278 return MakeIOError(filename_, base::File::ErrorToString(error),
292 kWritableFileAppend, error); 279 kWritableFileAppend, error);
293 } 280 }
294 281
295 return Status::OK(); 282 return Status::OK();
296 } 283 }
(...skipping 15 matching lines...) Expand all
312 if (!file_->Flush()) { 299 if (!file_->Flush()) {
313 base::File::Error error = LastFileError(); 300 base::File::Error error = LastFileError();
314 uma_logger_->RecordErrorAt(kWritableFileSync); 301 uma_logger_->RecordErrorAt(kWritableFileSync);
315 return MakeIOError(filename_, base::File::ErrorToString(error), 302 return MakeIOError(filename_, base::File::ErrorToString(error),
316 kWritableFileSync, error); 303 kWritableFileSync, error);
317 } 304 }
318 305
319 if (make_backup_ && file_type_ == kTable) 306 if (make_backup_ && file_type_ == kTable)
320 uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_)); 307 uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_));
321 308
322 return Status::OK(); 309 // leveldb's implicit contract for Sync() is that if this instance is for a
310 // manifest file then the directory is also sync'ed. See leveldb's
311 // env_posix.cc.
312 if (file_type_ == kManifest)
313 return SyncParent();
314 else
jsbell 2015/03/23 22:42:46 Nit: Remove else since there's an early return in
315 return Status::OK();
323 } 316 }
324 317
325 class IDBEnv : public ChromiumEnv { 318 class IDBEnv : public ChromiumEnv {
326 public: 319 public:
327 IDBEnv() : ChromiumEnv() { 320 IDBEnv() : ChromiumEnv() {
328 name_ = "LevelDBEnv.IDB"; 321 name_ = "LevelDBEnv.IDB";
329 make_backup_ = true; 322 make_backup_ = true;
330 } 323 }
331 }; 324 };
332 325
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 leveldb::WritableFile** result) { 874 leveldb::WritableFile** result) {
882 *result = NULL; 875 *result = NULL;
883 FilePath path = FilePath::FromUTF8Unsafe(fname); 876 FilePath path = FilePath::FromUTF8Unsafe(fname);
884 scoped_ptr<base::File> f(new base::File( 877 scoped_ptr<base::File> f(new base::File(
885 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE)); 878 path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE));
886 if (!f->IsValid()) { 879 if (!f->IsValid()) {
887 RecordErrorAt(kNewWritableFile); 880 RecordErrorAt(kNewWritableFile);
888 return MakeIOError(fname, "Unable to create writable file", 881 return MakeIOError(fname, "Unable to create writable file",
889 kNewWritableFile, f->error_details()); 882 kNewWritableFile, f->error_details());
890 } else { 883 } else {
891 *result = 884 *result = new ChromiumWritableFile(fname, f.release(), this, make_backup_);
892 new ChromiumWritableFile(fname, f.release(), this, this, make_backup_);
893 return Status::OK(); 885 return Status::OK();
894 } 886 }
895 } 887 }
896 888
897 Status ChromiumEnv::NewAppendableFile(const std::string& fname, 889 Status ChromiumEnv::NewAppendableFile(const std::string& fname,
898 leveldb::WritableFile** result) { 890 leveldb::WritableFile** result) {
899 *result = NULL; 891 *result = NULL;
900 FilePath path = FilePath::FromUTF8Unsafe(fname); 892 FilePath path = FilePath::FromUTF8Unsafe(fname);
901 scoped_ptr<base::File> f(new base::File( 893 scoped_ptr<base::File> f(new base::File(
902 path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND)); 894 path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND));
903 if (!f->IsValid()) { 895 if (!f->IsValid()) {
904 RecordErrorAt(kNewAppendableFile); 896 RecordErrorAt(kNewAppendableFile);
905 return MakeIOError(fname, "Unable to create appendable file", 897 return MakeIOError(fname, "Unable to create appendable file",
906 kNewAppendableFile, f->error_details()); 898 kNewAppendableFile, f->error_details());
907 } 899 }
908 *result = 900 *result = new ChromiumWritableFile(fname, f.release(), this, make_backup_);
909 new ChromiumWritableFile(fname, f.release(), this, this, make_backup_);
910 return Status::OK(); 901 return Status::OK();
911 } 902 }
912 903
913 uint64_t ChromiumEnv::NowMicros() { 904 uint64_t ChromiumEnv::NowMicros() {
914 return base::TimeTicks::Now().ToInternalValue(); 905 return base::TimeTicks::Now().ToInternalValue();
915 } 906 }
916 907
917 void ChromiumEnv::SleepForMicroseconds(int micros) { 908 void ChromiumEnv::SleepForMicroseconds(int micros) {
918 // Round up to the next millisecond. 909 // Round up to the next millisecond.
919 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); 910 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros));
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 mu_.Release(); 1055 mu_.Release();
1065 TRACE_EVENT0("leveldb", "ChromiumEnv::BGThread-Task"); 1056 TRACE_EVENT0("leveldb", "ChromiumEnv::BGThread-Task");
1066 (*function)(arg); 1057 (*function)(arg);
1067 } 1058 }
1068 } 1059 }
1069 1060
1070 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) { 1061 void ChromiumEnv::StartThread(void (*function)(void* arg), void* arg) {
1071 new Thread(function, arg); // Will self-delete. 1062 new Thread(function, arg); // Will self-delete.
1072 } 1063 }
1073 1064
1074 static std::string GetDirName(const std::string& filename) {
1075 return FilePath::FromUTF8Unsafe(filename).DirName().AsUTF8Unsafe();
1076 }
1077
1078 void ChromiumEnv::DidCreateNewFile(const std::string& filename) {
1079 base::AutoLock auto_lock(directory_sync_lock_);
1080 directories_needing_sync_.insert(GetDirName(filename));
1081 }
1082
1083 bool ChromiumEnv::DoesDirNeedSync(const std::string& filename) {
1084 base::AutoLock auto_lock(directory_sync_lock_);
1085 return ContainsKey(directories_needing_sync_, GetDirName(filename));
1086 }
1087
1088 void ChromiumEnv::DidSyncDir(const std::string& filename) {
1089 base::AutoLock auto_lock(directory_sync_lock_);
1090 directories_needing_sync_.erase(GetDirName(filename));
1091 }
1092
1093 } // namespace leveldb_env 1065 } // namespace leveldb_env
1094 1066
1095 namespace leveldb { 1067 namespace leveldb {
1096 1068
1097 Env* IDBEnv() { 1069 Env* IDBEnv() {
1098 return leveldb_env::idb_env.Pointer(); 1070 return leveldb_env::idb_env.Pointer();
1099 } 1071 }
1100 1072
1101 Env* Env::Default() { 1073 Env* Env::Default() {
1102 return leveldb_env::default_env.Pointer(); 1074 return leveldb_env::default_env.Pointer();
1103 } 1075 }
1104 1076
1105 } // namespace leveldb 1077 } // namespace leveldb
OLDNEW
« no previous file with comments | « third_party/leveldatabase/env_chromium.h ('k') | third_party/leveldatabase/env_chromium_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698