diff options
author | Marco Nelissen <marcone@google.com> | 2012-02-08 09:15:05 -0800 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2012-02-08 10:13:11 -0800 |
commit | 9ff4774cac499a376a59373d5bfb5112c9a2a004 (patch) | |
tree | 83003243e5755333153b5f17817701505be46bc3 | |
parent | ac259f17a0a6ba9e363bbf0c268c5942aab392c1 (diff) | |
download | frameworks_base-9ff4774cac499a376a59373d5bfb5112c9a2a004.zip frameworks_base-9ff4774cac499a376a59373d5bfb5112c9a2a004.tar.gz frameworks_base-9ff4774cac499a376a59373d5bfb5112c9a2a004.tar.bz2 |
Delete entries in bulk
Deleting entries from the database in bulk greatly speeds up the media
scanner in some cases; removing 31k entries used to take about 2 hours,
now it takes about 15 minutes.
Change-Id: Ia8f3fd6d828289e3d67178e9ad10399ded8d70d2
-rw-r--r-- | media/java/android/media/MediaScanner.java | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 9dc9cef..69ca58b 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -1150,9 +1150,44 @@ public class MediaScanner } } + static class MediaBulkDeleter { + StringBuilder idList = new StringBuilder(); + IContentProvider mProvider; + Uri mBaseUri; + + public MediaBulkDeleter(IContentProvider provider, Uri baseUri) { + mProvider = provider; + mBaseUri = baseUri; + } + + public void delete(long id) throws RemoteException { + if (idList.length() != 0) { + idList.append(","); + } + idList.append(id); + if (idList.length() > 1024) { + flush(); + } + } + public void flush() throws RemoteException { + int numrows = mProvider.delete(mBaseUri, MediaStore.MediaColumns._ID + " IN (" + + idList.toString() + ")", null); + //Log.i("@@@@@@@@@", "rows deleted: " + numrows); + idList.setLength(0); + } + } + private void postscan(String[] directories) throws RemoteException { Iterator<FileCacheEntry> iterator = mFileCache.values().iterator(); + // Tell the provider to not delete the file. + // If the file is truly gone the delete is unnecessary, and we want to avoid + // accidentally deleting files that are really there (this may happen if the + // filesystem is mounted and unmounted while the scanner is running). + Uri.Builder builder = mFilesUri.buildUpon(); + builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false"); + MediaBulkDeleter deleter = new MediaBulkDeleter(mMediaProvider, builder.build()); + while (iterator.hasNext()) { FileCacheEntry entry = iterator.next(); String path = entry.mPath; @@ -1176,15 +1211,6 @@ public class MediaScanner } if (fileMissing) { - // Tell the provider to not delete the file. - // If the file is truly gone the delete is unnecessary, and we want to avoid - // accidentally deleting files that are really there (this may happen if the - // filesystem is mounted and unmounted while the scanner is running). - Uri.Builder builder = mFilesUri.buildUpon(); - builder.appendEncodedPath(String.valueOf(entry.mRowId)); - builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false"); - Uri missingUri = builder.build(); - // do not delete missing playlists, since they may have been modified by the user. // the user can delete them in the media player instead. // instead, clear the path and lastModified fields in the row @@ -1192,15 +1218,17 @@ public class MediaScanner int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType); if (!MediaFile.isPlayListFileType(fileType)) { - mMediaProvider.delete(missingUri, null, null); + deleter.delete(entry.mRowId); iterator.remove(); if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) { + deleter.flush(); File f = new File(path); mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null); } } } } + deleter.flush(); // handle playlists last, after we know what media files are on the storage. if (mProcessPlaylists) { |