diff options
author | Marco Nelissen <marcone@google.com> | 2012-07-31 15:00:12 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2012-08-02 12:32:05 -0700 |
commit | 8ab2dc2f9680307febe997631c2148729f714e3d (patch) | |
tree | 25dbe904d90a3dce391452a8a51aac219676125c /media | |
parent | b1758cf8cd007bfffb3d8adceca25f3b0c82bd77 (diff) | |
download | frameworks_base-8ab2dc2f9680307febe997631c2148729f714e3d.zip frameworks_base-8ab2dc2f9680307febe997631c2148729f714e3d.tar.gz frameworks_base-8ab2dc2f9680307febe997631c2148729f714e3d.tar.bz2 |
Improve scan time for some cases
When the path being matched has a sqlite wildcard character in it, a "like"
match will be quite slow. Unfortunately this is fairly common, since "_"
is a wildcard character. However, because in most cases the case of the path
in the database will match the case on disk, an "=" match will work, so it
is worthwhile to try an "=" match first, before trying a "like".
If there are no wildcard characters, the "like" will be as fast as the "=",
because of the case-insensitive index on the _data column, so there is no
need to try "=" first in that case.
b/6751354
Change-Id: I1cd4efbd56a37886cb44a86acb73eb9a3c9f303d
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/MediaScanner.java | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 5cd5ff5..0d7b45e 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -1463,24 +1463,42 @@ public class MediaScanner } FileEntry makeEntryFor(String path) { - String key = path; String where; String[] selectionArgs; - if (mCaseInsensitivePaths) { - // the 'like' makes it use the index, the 'lower()' makes it correct - // when the path contains sqlite wildcard characters - where = "_data LIKE ?1 AND lower(_data)=lower(?1)"; - selectionArgs = new String[] { path }; - } else { - where = Files.FileColumns.DATA + "=?"; - selectionArgs = new String[] { path }; - } Cursor c = null; try { + boolean hasWildCards = path.contains("_") || path.contains("%"); + + if (hasWildCards || !mCaseInsensitivePaths) { + // if there are wildcard characters in the path, the "like" match + // will be slow, and it's worth trying an "=" comparison + // first, since in most cases the case will match. + // Also, we shouldn't do a "like" match on case-sensitive filesystems + where = Files.FileColumns.DATA + "=?"; + selectionArgs = new String[] { path }; + } else { + // if there are no wildcard characters in the path, then the "like" + // match will be just as fast as the "=" case, because of the index + where = "_data LIKE ?1 AND lower(_data)=lower(?1)"; + selectionArgs = new String[] { path }; + } c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION, where, selectionArgs, null, null); - if (c.moveToNext()) { + if (!c.moveToFirst() && hasWildCards && mCaseInsensitivePaths) { + // Try again with case-insensitive match. This will be slower, especially + // if the path contains wildcard characters. + // The 'like' makes it use the index, the 'lower()' makes it correct + // when the path contains sqlite wildcard characters, + where = "_data LIKE ?1 AND lower(_data)=lower(?1)"; + selectionArgs = new String[] { path }; + c.close(); + c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION, + where, selectionArgs, null, null); + // TODO update the path in the db with the correct case so the fast + // path works next time? + } + if (c.moveToFirst()) { long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX); long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX); |