| OLD | NEW |
| 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 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
| 10 #include <dirent.h> | 10 #include <dirent.h> |
| 11 #include <sys/types.h> | 11 #include <sys/types.h> |
| 12 #endif | 12 #endif |
| 13 | 13 |
| 14 #include "base/files/file_enumerator.h" | 14 #include "base/files/file_enumerator.h" |
| 15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
| 16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram_functions.h" |
| 19 #include "base/process/process_metrics.h" | 19 #include "base/process/process_metrics.h" |
| 20 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
| 24 #include "base/threading/thread_restrictions.h" | 24 #include "base/threading/thread_restrictions.h" |
| 25 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
| 26 #include "third_party/leveldatabase/chromium_logger.h" | 26 #include "third_party/leveldatabase/chromium_logger.h" |
| 27 #include "third_party/leveldatabase/src/include/leveldb/options.h" | 27 #include "third_party/leveldatabase/src/include/leveldb/options.h" |
| 28 #include "third_party/re2/src/re2/re2.h" | 28 #include "third_party/re2/src/re2/re2.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 result->push_back(FilePath::FromUTF8Unsafe(dent->d_name)); | 95 result->push_back(FilePath::FromUTF8Unsafe(dent->d_name)); |
| 96 } | 96 } |
| 97 int saved_errno = errno; | 97 int saved_errno = errno; |
| 98 closedir(dir); | 98 closedir(dir); |
| 99 if (readdir_result != 0) | 99 if (readdir_result != 0) |
| 100 return base::File::OSErrorToFileError(saved_errno); | 100 return base::File::OSErrorToFileError(saved_errno); |
| 101 return base::File::FILE_OK; | 101 return base::File::FILE_OK; |
| 102 #endif | 102 #endif |
| 103 } | 103 } |
| 104 | 104 |
| 105 // To avoid a dependency on storage_histograms.h and the storageLib, |
| 106 // we re-implement the BytesCountHistogram functions here. |
| 107 void RecordStorageBytesWritten(const char* label, int amount) { |
| 108 const std::string name = "Storage.BytesWritten."; |
| 109 base::UmaHistogramCounts10M(name + label, amount); |
| 110 } |
| 111 |
| 112 void RecordStorageBytesRead(const char* label, int amount) { |
| 113 const std::string name = "Storage.BytesRead."; |
| 114 base::UmaHistogramCounts10M(name + label, amount); |
| 115 } |
| 116 |
| 105 class ChromiumFileLock : public FileLock { | 117 class ChromiumFileLock : public FileLock { |
| 106 public: | 118 public: |
| 107 ChromiumFileLock(base::File file, const std::string& name) | 119 ChromiumFileLock(base::File file, const std::string& name) |
| 108 : file_(std::move(file)), name_(name) {} | 120 : file_(std::move(file)), name_(name) {} |
| 109 | 121 |
| 110 base::File file_; | 122 base::File file_; |
| 111 std::string name_; | 123 std::string name_; |
| 112 | 124 |
| 113 private: | 125 private: |
| 114 DISALLOW_COPY_AND_ASSIGN(ChromiumFileLock); | 126 DISALLOW_COPY_AND_ASSIGN(ChromiumFileLock); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 virtual ~ChromiumSequentialFile() {} | 181 virtual ~ChromiumSequentialFile() {} |
| 170 | 182 |
| 171 Status Read(size_t n, Slice* result, char* scratch) override { | 183 Status Read(size_t n, Slice* result, char* scratch) override { |
| 172 TRACE_EVENT1("leveldb", "ChromiumSequentialFile::Read", "size", n); | 184 TRACE_EVENT1("leveldb", "ChromiumSequentialFile::Read", "size", n); |
| 173 int bytes_read = file_.ReadAtCurrentPosNoBestEffort(scratch, n); | 185 int bytes_read = file_.ReadAtCurrentPosNoBestEffort(scratch, n); |
| 174 if (bytes_read == -1) { | 186 if (bytes_read == -1) { |
| 175 base::File::Error error = LastFileError(); | 187 base::File::Error error = LastFileError(); |
| 176 uma_logger_->RecordErrorAt(kSequentialFileRead); | 188 uma_logger_->RecordErrorAt(kSequentialFileRead); |
| 177 return MakeIOError(filename_, base::File::ErrorToString(error), | 189 return MakeIOError(filename_, base::File::ErrorToString(error), |
| 178 kSequentialFileRead, error); | 190 kSequentialFileRead, error); |
| 179 } else { | |
| 180 *result = Slice(scratch, bytes_read); | |
| 181 return Status::OK(); | |
| 182 } | 191 } |
| 192 if (bytes_read > 0) |
| 193 uma_logger_->RecordBytesRead(bytes_read); |
| 194 *result = Slice(scratch, bytes_read); |
| 195 return Status::OK(); |
| 183 } | 196 } |
| 184 | 197 |
| 185 Status Skip(uint64_t n) override { | 198 Status Skip(uint64_t n) override { |
| 186 if (file_.Seek(base::File::FROM_CURRENT, n) == -1) { | 199 if (file_.Seek(base::File::FROM_CURRENT, n) == -1) { |
| 187 base::File::Error error = LastFileError(); | 200 base::File::Error error = LastFileError(); |
| 188 uma_logger_->RecordErrorAt(kSequentialFileSkip); | 201 uma_logger_->RecordErrorAt(kSequentialFileSkip); |
| 189 return MakeIOError(filename_, base::File::ErrorToString(error), | 202 return MakeIOError(filename_, base::File::ErrorToString(error), |
| 190 kSequentialFileSkip, error); | 203 kSequentialFileSkip, error); |
| 191 } else { | 204 } else { |
| 192 return Status::OK(); | 205 return Status::OK(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 208 const UMALogger* uma_logger) | 221 const UMALogger* uma_logger) |
| 209 : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {} | 222 : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {} |
| 210 virtual ~ChromiumRandomAccessFile() {} | 223 virtual ~ChromiumRandomAccessFile() {} |
| 211 | 224 |
| 212 Status Read(uint64_t offset, | 225 Status Read(uint64_t offset, |
| 213 size_t n, | 226 size_t n, |
| 214 Slice* result, | 227 Slice* result, |
| 215 char* scratch) const override { | 228 char* scratch) const override { |
| 216 TRACE_EVENT2("leveldb", "ChromiumRandomAccessFile::Read", "offset", offset, | 229 TRACE_EVENT2("leveldb", "ChromiumRandomAccessFile::Read", "offset", offset, |
| 217 "size", n); | 230 "size", n); |
| 218 Status s; | 231 int bytes_read = file_.Read(offset, scratch, n); |
| 219 int r = file_.Read(offset, scratch, n); | 232 *result = Slice(scratch, (bytes_read < 0) ? 0 : bytes_read); |
| 220 *result = Slice(scratch, (r < 0) ? 0 : r); | 233 if (bytes_read < 0) { |
| 221 if (r < 0) { | |
| 222 // An error: return a non-ok status | |
| 223 s = MakeIOError(filename_, "Could not perform read", | |
| 224 kRandomAccessFileRead); | |
| 225 uma_logger_->RecordErrorAt(kRandomAccessFileRead); | 234 uma_logger_->RecordErrorAt(kRandomAccessFileRead); |
| 235 return MakeIOError(filename_, "Could not perform read", |
| 236 kRandomAccessFileRead); |
| 226 } | 237 } |
| 227 return s; | 238 if (bytes_read > 0) |
| 239 uma_logger_->RecordBytesRead(bytes_read); |
| 240 return Status::OK(); |
| 228 } | 241 } |
| 229 | 242 |
| 230 private: | 243 private: |
| 231 std::string filename_; | 244 std::string filename_; |
| 232 mutable base::File file_; | 245 mutable base::File file_; |
| 233 const UMALogger* uma_logger_; | 246 const UMALogger* uma_logger_; |
| 234 | 247 |
| 235 DISALLOW_COPY_AND_ASSIGN(ChromiumRandomAccessFile); | 248 DISALLOW_COPY_AND_ASSIGN(ChromiumRandomAccessFile); |
| 236 }; | 249 }; |
| 237 | 250 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 Status ChromiumWritableFile::Append(const Slice& data) { | 309 Status ChromiumWritableFile::Append(const Slice& data) { |
| 297 DCHECK(file_.IsValid()); | 310 DCHECK(file_.IsValid()); |
| 298 DCHECK(uma_logger_); | 311 DCHECK(uma_logger_); |
| 299 int bytes_written = file_.WriteAtCurrentPos(data.data(), data.size()); | 312 int bytes_written = file_.WriteAtCurrentPos(data.data(), data.size()); |
| 300 if (bytes_written != data.size()) { | 313 if (bytes_written != data.size()) { |
| 301 base::File::Error error = LastFileError(); | 314 base::File::Error error = LastFileError(); |
| 302 uma_logger_->RecordOSError(kWritableFileAppend, error); | 315 uma_logger_->RecordOSError(kWritableFileAppend, error); |
| 303 return MakeIOError(filename_, base::File::ErrorToString(error), | 316 return MakeIOError(filename_, base::File::ErrorToString(error), |
| 304 kWritableFileAppend, error); | 317 kWritableFileAppend, error); |
| 305 } | 318 } |
| 306 | 319 if (bytes_written > 0) |
| 320 uma_logger_->RecordBytesWritten(bytes_written); |
| 307 return Status::OK(); | 321 return Status::OK(); |
| 308 } | 322 } |
| 309 | 323 |
| 310 Status ChromiumWritableFile::Close() { | 324 Status ChromiumWritableFile::Close() { |
| 311 file_.Close(); | 325 file_.Close(); |
| 312 return Status::OK(); | 326 return Status::OK(); |
| 313 } | 327 } |
| 314 | 328 |
| 315 Status ChromiumWritableFile::Flush() { | 329 Status ChromiumWritableFile::Flush() { |
| 316 // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing to | 330 // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing to |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 | 919 |
| 906 void ChromiumEnv::SleepForMicroseconds(int micros) { | 920 void ChromiumEnv::SleepForMicroseconds(int micros) { |
| 907 // Round up to the next millisecond. | 921 // Round up to the next millisecond. |
| 908 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); | 922 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); |
| 909 } | 923 } |
| 910 | 924 |
| 911 void ChromiumEnv::RecordErrorAt(MethodID method) const { | 925 void ChromiumEnv::RecordErrorAt(MethodID method) const { |
| 912 GetMethodIOErrorHistogram()->Add(method); | 926 GetMethodIOErrorHistogram()->Add(method); |
| 913 } | 927 } |
| 914 | 928 |
| 915 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { | |
| 916 GetLockFileAncestorHistogram()->Add(num_missing_ancestors); | |
| 917 } | |
| 918 | |
| 919 void ChromiumEnv::RecordOSError(MethodID method, | 929 void ChromiumEnv::RecordOSError(MethodID method, |
| 920 base::File::Error error) const { | 930 base::File::Error error) const { |
| 921 DCHECK_LT(error, 0); | 931 DCHECK_LT(error, 0); |
| 922 RecordErrorAt(method); | 932 RecordErrorAt(method); |
| 923 GetOSErrorHistogram(method, -base::File::FILE_ERROR_MAX)->Add(-error); | 933 GetOSErrorHistogram(method, -base::File::FILE_ERROR_MAX)->Add(-error); |
| 924 } | 934 } |
| 925 | 935 |
| 936 void ChromiumEnv::RecordBytesRead(int amount) const { |
| 937 RecordStorageBytesRead(name_.c_str(), amount); |
| 938 } |
| 939 |
| 940 void ChromiumEnv::RecordBytesWritten(int amount) const { |
| 941 RecordStorageBytesWritten(name_.c_str(), amount); |
| 942 } |
| 943 |
| 944 void ChromiumEnv::RecordLockFileAncestors(int num_missing_ancestors) const { |
| 945 GetLockFileAncestorHistogram()->Add(num_missing_ancestors); |
| 946 } |
| 947 |
| 926 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, | 948 base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, |
| 927 int limit) const { | 949 int limit) const { |
| 928 std::string uma_name; | 950 std::string uma_name; |
| 929 base::StringAppendF(&uma_name, "%s.%s", uma_ioerror_base_name_.c_str(), | 951 base::StringAppendF(&uma_name, "%s.%s", uma_ioerror_base_name_.c_str(), |
| 930 MethodIDToString(method)); | 952 MethodIDToString(method)); |
| 931 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, | 953 return base::LinearHistogram::FactoryGet(uma_name, 1, limit, limit + 1, |
| 932 base::Histogram::kUmaTargetedHistogramFlag); | 954 base::Histogram::kUmaTargetedHistogramFlag); |
| 933 } | 955 } |
| 934 | 956 |
| 935 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { | 957 base::HistogramBase* ChromiumEnv::GetMethodIOErrorHistogram() const { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 | 1095 |
| 1074 } // namespace leveldb_env | 1096 } // namespace leveldb_env |
| 1075 | 1097 |
| 1076 namespace leveldb { | 1098 namespace leveldb { |
| 1077 | 1099 |
| 1078 Env* Env::Default() { | 1100 Env* Env::Default() { |
| 1079 return leveldb_env::default_env.Pointer(); | 1101 return leveldb_env::default_env.Pointer(); |
| 1080 } | 1102 } |
| 1081 | 1103 |
| 1082 } // namespace leveldb | 1104 } // namespace leveldb |
| OLD | NEW |