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

Side by Side Diff: sql/vfs_wrapper.cc

Issue 2727103003: [sql] Histograms for I/O calls seen by browser VFS. (Closed)
Patch Set: Use histogram suffixes. Created 3 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
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 The Chromium 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. 3 // found in the LICENSE file.
4 4
5 #include "sql/vfs_wrapper.h" 5 #include "sql/vfs_wrapper.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/debug/leak_annotations.h" 11 #include "base/debug/leak_annotations.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h"
14 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
15 16
16 #if defined(OS_MACOSX) && !defined(OS_IOS) 17 #if defined(OS_MACOSX) && !defined(OS_IOS)
17 #include <CoreFoundation/CoreFoundation.h> 18 #include <CoreFoundation/CoreFoundation.h>
18 #include <CoreServices/CoreServices.h> 19 #include <CoreServices/CoreServices.h>
19 20
20 #include "base/mac/mac_util.h" 21 #include "base/mac/mac_util.h"
21 #include "base/mac/scoped_cftyperef.h" 22 #include "base/mac/scoped_cftyperef.h"
22 #endif 23 #endif
23 24
24 namespace sql { 25 namespace sql {
25 namespace { 26 namespace {
26 27
27 // https://www.sqlite.org/vfs.html - documents the overall VFS system. 28 // https://www.sqlite.org/vfs.html - documents the overall VFS system.
28 // 29 //
29 // https://www.sqlite.org/c3ref/vfs.html - VFS methods. This code tucks the 30 // https://www.sqlite.org/c3ref/vfs.html - VFS methods. This code tucks the
30 // wrapped VFS pointer into the wrapper's pAppData pointer. 31 // wrapped VFS pointer into the wrapper's pAppData pointer.
31 // 32 //
32 // https://www.sqlite.org/c3ref/file.html - instance of an open file. This code 33 // https://www.sqlite.org/c3ref/file.html - instance of an open file. This code
33 // allocates a VfsFile for this, which contains a pointer to the wrapped file. 34 // allocates a VfsFile for this, which contains a pointer to the wrapped file.
34 // Idiomatic SQLite would take the wrapped VFS szOsFile and increase it to store 35 // Idiomatic SQLite would take the wrapped VFS szOsFile and increase it to store
35 // additional data as a prefix. 36 // additional data as a prefix.
36 37
38 // This enum must match the numbering from Sqlite.VfsEvents in histograms.xml.
39 // Do not reorder or remove items, only add new items before VFS_EVENT_MAX.
40 enum VfsEventType {
41 // VFS method xOpen() call.
42 VFS_OPEN = 0,
43
44 // VFS method xDelete() call.
45 VFS_DELETE,
46
47 // VFS method xAccess() call.
48 VFS_ACCESS,
49
50 // VFS method xFullPathname() call.
51 VFS_FULLPATHNAME,
52
53 // I/O method xClose() call, should balance VFS_OPEN.
54 VFS_IO_CLOSE,
55
56 // I/O method xRead() call.
57 VFS_IO_READ,
58
59 // I/O method xWrite() call.
60 VFS_IO_WRITE,
61
62 // I/O method xTruncate() call.
63 VFS_IO_TRUNCATE,
64
65 // I/O method xSync() call.
66 VFS_IO_SYNC,
67
68 // I/O method xFileSize() call.
69 VFS_IO_FILESIZE,
70
71 // I/O method xFetch() call. This is like xRead(), but when using
72 // memory-mapping.
73 VFS_IO_FETCH,
74
75 // Add new items before this one, always keep this one at the end.
76 VFS_EVENT_MAX
77 };
78
79 // TODO(shess): If the VFS was parameterized, then results could be binned by
80 // database. It would require a separate VFS per database, though the variants
81 // could all use the same VFS functions.
82 void RecordVfsEvent(VfsEventType vfs_event) {
83 UMA_HISTOGRAM_ENUMERATION("Sqlite.Vfs_Events", vfs_event, VFS_EVENT_MAX);
84 }
85
37 sqlite3_vfs* GetWrappedVfs(sqlite3_vfs* wrapped_vfs) { 86 sqlite3_vfs* GetWrappedVfs(sqlite3_vfs* wrapped_vfs) {
38 return static_cast<sqlite3_vfs*>(wrapped_vfs->pAppData); 87 return static_cast<sqlite3_vfs*>(wrapped_vfs->pAppData);
39 } 88 }
40 89
41 // NOTE(shess): This structure is allocated by SQLite using malloc. Do not add 90 // NOTE(shess): This structure is allocated by SQLite using malloc. Do not add
42 // C++ objects, they will not be correctly constructed and destructed. Instead, 91 // C++ objects, they will not be correctly constructed and destructed. Instead,
43 // manually manage a pointer to a C++ object in Open() and Close(). 92 // manually manage a pointer to a C++ object in Open() and Close().
44 struct VfsFile { 93 struct VfsFile {
45 const sqlite3_io_methods* methods; 94 const sqlite3_io_methods* methods;
46 sqlite3_file* wrapped_file; 95 sqlite3_file* wrapped_file;
47 }; 96 };
48 97
49 VfsFile* AsVfsFile(sqlite3_file* wrapper_file) { 98 VfsFile* AsVfsFile(sqlite3_file* wrapper_file) {
50 return reinterpret_cast<VfsFile*>(wrapper_file); 99 return reinterpret_cast<VfsFile*>(wrapper_file);
51 } 100 }
52 101
53 sqlite3_file* GetWrappedFile(sqlite3_file* wrapper_file) { 102 sqlite3_file* GetWrappedFile(sqlite3_file* wrapper_file) {
54 return AsVfsFile(wrapper_file)->wrapped_file; 103 return AsVfsFile(wrapper_file)->wrapped_file;
55 } 104 }
56 105
57 int Close(sqlite3_file* sqlite_file) 106 int Close(sqlite3_file* sqlite_file)
58 { 107 {
108 RecordVfsEvent(VFS_IO_CLOSE);
109
59 VfsFile* file = AsVfsFile(sqlite_file); 110 VfsFile* file = AsVfsFile(sqlite_file);
60 111
61 int r = file->wrapped_file->pMethods->xClose(file->wrapped_file); 112 int r = file->wrapped_file->pMethods->xClose(file->wrapped_file);
62 sqlite3_free(file->wrapped_file); 113 sqlite3_free(file->wrapped_file);
63 memset(file, '\0', sizeof(*file)); 114 memset(file, '\0', sizeof(*file));
64 return r; 115 return r;
65 } 116 }
66 117
67 int Read(sqlite3_file* sqlite_file, void* buf, int amt, sqlite3_int64 ofs) 118 int Read(sqlite3_file* sqlite_file, void* buf, int amt, sqlite3_int64 ofs)
68 { 119 {
120 RecordVfsEvent(VFS_IO_READ);
121 UMA_HISTOGRAM_COUNTS("Sqlite.Vfs_Read", amt);
122
69 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 123 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
70 return wrapped_file->pMethods->xRead(wrapped_file, buf, amt, ofs); 124 return wrapped_file->pMethods->xRead(wrapped_file, buf, amt, ofs);
71 } 125 }
72 126
73 int Write(sqlite3_file* sqlite_file, const void* buf, int amt, 127 int Write(sqlite3_file* sqlite_file, const void* buf, int amt,
74 sqlite3_int64 ofs) 128 sqlite3_int64 ofs)
75 { 129 {
130 RecordVfsEvent(VFS_IO_WRITE);
131 UMA_HISTOGRAM_COUNTS("Sqlite.Vfs_Write", amt);
132
76 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 133 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
77 return wrapped_file->pMethods->xWrite(wrapped_file, buf, amt, ofs); 134 return wrapped_file->pMethods->xWrite(wrapped_file, buf, amt, ofs);
78 } 135 }
79 136
80 int Truncate(sqlite3_file* sqlite_file, sqlite3_int64 size) 137 int Truncate(sqlite3_file* sqlite_file, sqlite3_int64 size)
81 { 138 {
139 RecordVfsEvent(VFS_IO_TRUNCATE);
140
82 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 141 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
83 return wrapped_file->pMethods->xTruncate(wrapped_file, size); 142 return wrapped_file->pMethods->xTruncate(wrapped_file, size);
84 } 143 }
85 144
86 int Sync(sqlite3_file* sqlite_file, int flags) 145 int Sync(sqlite3_file* sqlite_file, int flags)
87 { 146 {
147 RecordVfsEvent(VFS_IO_SYNC);
148
88 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 149 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
89 return wrapped_file->pMethods->xSync(wrapped_file, flags); 150 return wrapped_file->pMethods->xSync(wrapped_file, flags);
90 } 151 }
91 152
92 int FileSize(sqlite3_file* sqlite_file, sqlite3_int64* size) 153 int FileSize(sqlite3_file* sqlite_file, sqlite3_int64* size)
93 { 154 {
155 RecordVfsEvent(VFS_IO_FILESIZE);
156
94 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 157 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
95 return wrapped_file->pMethods->xFileSize(wrapped_file, size); 158 return wrapped_file->pMethods->xFileSize(wrapped_file, size);
96 } 159 }
97 160
98 int Lock(sqlite3_file* sqlite_file, int file_lock) 161 int Lock(sqlite3_file* sqlite_file, int file_lock)
99 { 162 {
100 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 163 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
101 return wrapped_file->pMethods->xLock(wrapped_file, file_lock); 164 return wrapped_file->pMethods->xLock(wrapped_file, file_lock);
102 } 165 }
103 166
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 210 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
148 wrapped_file->pMethods->xShmBarrier(wrapped_file); 211 wrapped_file->pMethods->xShmBarrier(wrapped_file);
149 } 212 }
150 213
151 int ShmUnmap(sqlite3_file *sqlite_file, int del) { 214 int ShmUnmap(sqlite3_file *sqlite_file, int del) {
152 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 215 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
153 return wrapped_file->pMethods->xShmUnmap(wrapped_file, del); 216 return wrapped_file->pMethods->xShmUnmap(wrapped_file, del);
154 } 217 }
155 218
156 int Fetch(sqlite3_file *sqlite_file, sqlite3_int64 off, int amt, void **pp) { 219 int Fetch(sqlite3_file *sqlite_file, sqlite3_int64 off, int amt, void **pp) {
220 RecordVfsEvent(VFS_IO_FETCH);
221 UMA_HISTOGRAM_COUNTS("Sqlite.Vfs_Fetch", amt);
222
157 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 223 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
158 return wrapped_file->pMethods->xFetch(wrapped_file, off, amt, pp); 224 return wrapped_file->pMethods->xFetch(wrapped_file, off, amt, pp);
159 } 225 }
160 226
161 int Unfetch(sqlite3_file *sqlite_file, sqlite3_int64 off, void *p) { 227 int Unfetch(sqlite3_file *sqlite_file, sqlite3_int64 off, void *p) {
162 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file); 228 sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
163 return wrapped_file->pMethods->xUnfetch(wrapped_file, off, p); 229 return wrapped_file->pMethods->xUnfetch(wrapped_file, off, p);
164 } 230 }
165 231
166 #if defined(OS_MACOSX) && !defined(OS_IOS) 232 #if defined(OS_MACOSX) && !defined(OS_IOS)
167 // Helper to convert a POSIX path into a CoreFoundation path. 233 // Helper to convert a POSIX path into a CoreFoundation path.
168 base::ScopedCFTypeRef<CFURLRef> CFURLRefForPath(const char* path){ 234 base::ScopedCFTypeRef<CFURLRef> CFURLRefForPath(const char* path){
169 base::ScopedCFTypeRef<CFStringRef> urlString( 235 base::ScopedCFTypeRef<CFStringRef> urlString(
170 CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path)); 236 CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path));
171 base::ScopedCFTypeRef<CFURLRef> url( 237 base::ScopedCFTypeRef<CFURLRef> url(
172 CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlString, 238 CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlString,
173 kCFURLPOSIXPathStyle, FALSE)); 239 kCFURLPOSIXPathStyle, FALSE));
174 return url; 240 return url;
175 } 241 }
176 #endif 242 #endif
177 243
178 int Open(sqlite3_vfs* vfs, const char* file_name, sqlite3_file* wrapper_file, 244 int Open(sqlite3_vfs* vfs, const char* file_name, sqlite3_file* wrapper_file,
179 int desired_flags, int* used_flags) { 245 int desired_flags, int* used_flags) {
246 RecordVfsEvent(VFS_OPEN);
247
180 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs); 248 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
181 249
182 sqlite3_file* wrapped_file = static_cast<sqlite3_file*>( 250 sqlite3_file* wrapped_file = static_cast<sqlite3_file*>(
183 sqlite3_malloc(wrapped_vfs->szOsFile)); 251 sqlite3_malloc(wrapped_vfs->szOsFile));
184 if (!wrapped_file) 252 if (!wrapped_file)
185 return SQLITE_NOMEM; 253 return SQLITE_NOMEM;
186 254
187 // NOTE(shess): SQLite's unixOpen() makes assumptions about the structure of 255 // NOTE(shess): SQLite's unixOpen() makes assumptions about the structure of
188 // |file_name|. Do not pass a local copy, here, only the passed-in value. 256 // |file_name|. Do not pass a local copy, here, only the passed-in value.
189 int rc = wrapped_vfs->xOpen(wrapped_vfs, 257 int rc = wrapped_vfs->xOpen(wrapped_vfs,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 // Methods above are valid for version 2. 359 // Methods above are valid for version 2.
292 Fetch, 360 Fetch,
293 Unfetch, 361 Unfetch,
294 }; 362 };
295 file->methods = &io_methods; 363 file->methods = &io_methods;
296 } 364 }
297 return SQLITE_OK; 365 return SQLITE_OK;
298 } 366 }
299 367
300 int Delete(sqlite3_vfs* vfs, const char* file_name, int sync_dir) { 368 int Delete(sqlite3_vfs* vfs, const char* file_name, int sync_dir) {
369 RecordVfsEvent(VFS_DELETE);
370
301 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs); 371 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
302 return wrapped_vfs->xDelete(wrapped_vfs, file_name, sync_dir); 372 return wrapped_vfs->xDelete(wrapped_vfs, file_name, sync_dir);
303 } 373 }
304 374
305 int Access(sqlite3_vfs* vfs, const char* file_name, int flag, int* res) { 375 int Access(sqlite3_vfs* vfs, const char* file_name, int flag, int* res) {
376 RecordVfsEvent(VFS_ACCESS);
377
306 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs); 378 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
307 return wrapped_vfs->xAccess(wrapped_vfs, file_name, flag, res); 379 return wrapped_vfs->xAccess(wrapped_vfs, file_name, flag, res);
308 } 380 }
309 381
310 int FullPathname(sqlite3_vfs* vfs, const char* relative_path, 382 int FullPathname(sqlite3_vfs* vfs, const char* relative_path,
311 int buf_size, char* absolute_path) { 383 int buf_size, char* absolute_path) {
384 RecordVfsEvent(VFS_FULLPATHNAME);
385
312 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs); 386 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
313 return wrapped_vfs->xFullPathname( 387 return wrapped_vfs->xFullPathname(
314 wrapped_vfs, relative_path, buf_size, absolute_path); 388 wrapped_vfs, relative_path, buf_size, absolute_path);
315 } 389 }
316 390
317 void* DlOpen(sqlite3_vfs* vfs, const char* filename) { 391 void* DlOpen(sqlite3_vfs* vfs, const char* filename) {
318 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs); 392 sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
319 return wrapped_vfs->xDlOpen(wrapped_vfs, filename); 393 return wrapped_vfs->xDlOpen(wrapped_vfs, filename);
320 } 394 }
321 395
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 512
439 if (SQLITE_OK == sqlite3_vfs_register(wrapper_vfs.get(), 0)) { 513 if (SQLITE_OK == sqlite3_vfs_register(wrapper_vfs.get(), 0)) {
440 ANNOTATE_LEAKING_OBJECT_PTR(wrapper_vfs.get()); 514 ANNOTATE_LEAKING_OBJECT_PTR(wrapper_vfs.get());
441 wrapper_vfs.release(); 515 wrapper_vfs.release();
442 } 516 }
443 517
444 return sqlite3_vfs_find(kVFSName); 518 return sqlite3_vfs_find(kVFSName);
445 } 519 }
446 520
447 } // namespace sql 521 } // namespace sql
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698