From 33ed0626ffcfbf9c83727cf55b2f02be693d1d94 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 3 May 2017 13:14:30 +0200 Subject: [PATCH] speedup search --- .../datamodel/FileDataStorageManager.java | 114 ++++++++++-------- .../ui/adapter/FileListListAdapter.java | 43 +++++-- 2 files changed, 97 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 57d779c7c5..4f649c24f5 100644 --- a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -1,21 +1,20 @@ /** - * ownCloud Android client application - * - * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2015 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * + * ownCloud Android client application + *

+ * Copyright (C) 2012 Bartek Przybylski + * Copyright (C) 2015 ownCloud Inc. + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package com.owncloud.android.datamodel; @@ -164,7 +163,7 @@ public class FileDataStorageManager { // TODO better implementation, filtering in the access to database instead of here Vector tmp = getFolderContent(folder, onlyOnDevice); OCFile current = null; - for (int i=0; i updatedFiles, Collection filesToRemove ) { - Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove"); ArrayList operations = @@ -371,7 +370,7 @@ public class FileDataStorageManager { // prepare operations to remove files in the given folder String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?"; - String [] whereArgs = null; + String[] whereArgs = null; for (OCFile file : filesToRemove) { if (file.getParentId() == folder.getFileId()) { whereArgs = new String[]{mAccount.name, file.getRemotePath()}; @@ -536,7 +535,7 @@ public class FileDataStorageManager { Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" + folder.getFileId()); // URI // for recursive deletion String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?"; - String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()}; + String[] whereArgs = new String[]{mAccount.name, folder.getRemotePath()}; int deleted = 0; if (getContentProviderClient() != null) { try { @@ -830,9 +829,9 @@ public class FileDataStorageManager { if (c != null && c.moveToFirst()) { do { OCFile child = createFileInstance(c); - if (child.isFolder() || !onlyOnDevice || child.isDown()) { - ret.add(child); - } + if (child.isFolder() || !onlyOnDevice || child.isDown()) { + ret.add(child); + } } while (c.moveToNext()); c.close(); } @@ -1024,7 +1023,7 @@ public class FileDataStorageManager { * Retrieves an stored {@link OCShare} given its id. * * @param id Identifier. - * @return Stored {@link OCShare} given its id. + * @return Stored {@link OCShare} given its id. */ public OCShare getShareById(long id) { OCShare share = null; @@ -1082,7 +1081,7 @@ public class FileDataStorageManager { .query(ProviderTableMeta.CONTENT_URI_SHARE, null, key + AND - + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", + + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?", new String[]{value, mAccount.name}, null ); @@ -1096,7 +1095,7 @@ public class FileDataStorageManager { null ); } catch (RemoteException e) { - Log_OC.w(TAG, "Could not get details, assuming share does not exist: "+ e.getMessage()); + Log_OC.w(TAG, "Could not get details, assuming share does not exist: " + e.getMessage()); c = null; } } @@ -1104,14 +1103,13 @@ public class FileDataStorageManager { } - /** * Get first share bound to a file with a known path and given {@link ShareType}. * * @param path Path of the file. * @param type Type of the share to get * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK} - * @return First {@link OCShare} instance found in DB bound to the file in 'path' + * @return First {@link OCShare} instance found in DB bound to the file in 'path' */ public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) { Cursor cursor = null; @@ -1121,12 +1119,12 @@ public class FileDataStorageManager { String selection = ProviderTableMeta.OCSHARES_PATH + AND + ProviderTableMeta.OCSHARES_SHARE_TYPE + AND - + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ; + + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; if (!ShareType.PUBLIC_LINK.equals(type)) { selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?"; } - String [] selectionArgs; + String[] selectionArgs; if (ShareType.PUBLIC_LINK.equals(type)) { selectionArgs = new String[]{ path, @@ -1219,7 +1217,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PARENT + "=?"; - String [] whereArgs = new String[] { mAccount.name , String.valueOf(folder.getFileId()) }; + String[] whereArgs = new String[]{mAccount.name, String.valueOf(folder.getFileId())}; if (getContentResolver() != null) { getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); @@ -1233,13 +1231,13 @@ public class FileDataStorageManager { } } - private void resetShareFlagInAFile(String filePath){ + private void resetShareFlagInAFile(String filePath) { ContentValues cv = new ContentValues(); cv.put(ProviderTableMeta.FILE_SHARED_VIA_LINK, false); cv.put(ProviderTableMeta.FILE_SHARED_WITH_SHAREE, false); cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, ""); - String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH+ "=?"; - String [] whereArgs = new String[] { mAccount.name , filePath }; + String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + "=?"; + String[] whereArgs = new String[]{mAccount.name, filePath}; if (getContentResolver() != null) { getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs); @@ -1426,7 +1424,7 @@ public class FileDataStorageManager { Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE; String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND + ProviderTableMeta._ID + "=?"; - String [] whereArgs = new String[]{mAccount.name, Long.toString(share.getId())}; + String[] whereArgs = new String[]{mAccount.name, Long.toString(share.getId())}; if (getContentProviderClient() != null) { try { getContentProviderClient().delete(share_uri, where, whereArgs); @@ -1443,16 +1441,16 @@ public class FileDataStorageManager { // Reset flags & Remove shares for this files String filePath = ""; - for (OCShare share: shares) { - if (filePath != share.getPath()){ + for (OCShare share : shares) { + if (filePath != share.getPath()) { filePath = share.getPath(); resetShareFlagInAFile(filePath); operations = prepareRemoveSharesInFile(filePath, operations); } } - // Add operations to insert shares - operations = prepareInsertShares(shares, operations); + // Add operations to insert shares + operations = prepareInsertShares(shares, operations); // apply operations in batch if (operations.size() > 0) { @@ -1593,7 +1591,7 @@ public class FileDataStorageManager { if (folder != null) { String where = ProviderTableMeta.OCSHARES_PATH + AND + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?"; - String [] whereArgs = new String[]{ "", mAccount.name }; + String[] whereArgs = new String[]{"", mAccount.name}; Vector files = getFolderContent(folder, false); @@ -1627,15 +1625,15 @@ public class FileDataStorageManager { } - public ArrayList getSharesWithForAFile(String filePath, String accountName){ + public ArrayList getSharesWithForAFile(String filePath, String accountName) { // Condition String where = ProviderTableMeta.OCSHARES_PATH + AND + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + AND + " (" + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " - + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " - + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? OR " + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? ) "; - String [] whereArgs = new String[]{ filePath, accountName , + String[] whereArgs = new String[]{filePath, accountName, Integer.toString(ShareType.USER.getValue()), Integer.toString(ShareType.GROUP.getValue()), Integer.toString(ShareType.EMAIL.getValue()), @@ -1734,7 +1732,7 @@ public class FileDataStorageManager { ProviderTableMeta.CONTENT_URI_FILE, cv, ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(file.getFileId())} + new String[]{String.valueOf(file.getFileId())} ); } else { try { @@ -1871,7 +1869,7 @@ public class FileDataStorageManager { } - public OCCapability saveCapabilities(OCCapability capability){ + public OCCapability saveCapabilities(OCCapability capability) { // Prepare capabilities data ContentValues cv = new ContentValues(); @@ -1958,7 +1956,7 @@ public class FileDataStorageManager { return exists; } - private Cursor getCapabilityCursorForAccount(String accountName){ + private Cursor getCapabilityCursorForAccount(String accountName) { Cursor c = null; if (getContentResolver() != null) { c = getContentResolver() @@ -1981,7 +1979,8 @@ public class FileDataStorageManager { return c; } - public OCCapability getCapability(String accountName){ + + public OCCapability getCapability(String accountName) { OCCapability capability = null; Cursor c = getCapabilityCursorForAccount(accountName); @@ -2065,6 +2064,19 @@ public class FileDataStorageManager { } } + public void saveVirtuals(VirtualFolderType type, List values) { + + if (getContentResolver() != null) { + getContentResolver().bulkInsert(ProviderTableMeta.CONTENT_URI_VIRTUAL, values.toArray(new ContentValues[values.size()])); + } else { + try { + getContentProviderClient().bulkInsert(ProviderTableMeta.CONTENT_URI_VIRTUAL, values.toArray(new ContentValues[values.size()])); + } catch (RemoteException e) { + Log_OC.e(TAG, FAILED_TO_INSERT_MSG + e.getMessage(), e); + } + } + } + public void saveVirtual(VirtualFolderType type, OCFile file) { ContentValues cv = new ContentValues(); cv.put(ProviderTableMeta.VIRTUAL_TYPE, type.toString()); @@ -2112,7 +2124,7 @@ public class FileDataStorageManager { if (c != null && c.moveToFirst()) { do { OCFile child = createFileInstanceFromVirtual(c); - ocFiles.add(child); + ocFiles.add(child); } while (c.moveToNext()); c.close(); } diff --git a/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java index 099df3d284..0eeae615bd 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -24,6 +24,7 @@ package com.owncloud.android.ui.adapter; import android.accounts.Account; +import android.content.ContentValues; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; @@ -48,6 +49,7 @@ import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.datamodel.VirtualFolderType; import com.owncloud.android.db.PreferenceManager; +import com.owncloud.android.db.ProviderMeta; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -485,10 +487,14 @@ public class FileListListAdapter extends BaseAdapter { public void setData(ArrayList objects, ExtendedListFragment.SearchType searchType) { mFiles = new Vector<>(); - if (searchType.equals(ExtendedListFragment.SearchType.SHARED_FILTER)) { - parseShares(objects); - } else { - parseVirtuals(objects, searchType); + + // early exit + if (objects.size() > 0) { + if (searchType.equals(ExtendedListFragment.SearchType.SHARED_FILTER)) { + parseShares(objects); + } else { + parseVirtuals(objects, searchType); + } } if (!searchType.equals(ExtendedListFragment.SearchType.PHOTO_SEARCH) && @@ -558,14 +564,33 @@ public class FileListListAdapter extends BaseAdapter { mStorageManager.deleteVirtuals(type); + ArrayList contentValues = new ArrayList<>(); + for (int i = 0; i < objects.size(); i++) { - OCFile ocFile = FileStorageUtils.fillOCFile((RemoteFile) objects.get(i)); - searchForLocalFileInDefaultPath(ocFile); - ocFile = mStorageManager.saveFileWithParent(ocFile, mContext); - mStorageManager.saveVirtual(type, ocFile); + OCFile ocFile; + + // try to find it in database + ocFile = mStorageManager.getFileByPath(((RemoteFile) objects.get(i)).getRemotePath()); + + if (ocFile == null) { + // new + ocFile = FileStorageUtils.fillOCFile((RemoteFile) objects.get(i)); + searchForLocalFileInDefaultPath(ocFile); + ocFile = mStorageManager.saveFileWithParent(ocFile, mContext); + } + + if (!onlyImages || MimeTypeUtil.isImage(ocFile)) { + mFiles.add(ocFile); + } + + ContentValues cv = new ContentValues(); + cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_TYPE, type.toString()); + cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_OCFILE_ID, ocFile.getFileId()); + + contentValues.add(cv); } - mFiles.addAll(mStorageManager.getVirtualFolderContent(type, onlyImages)); + mStorageManager.saveVirtuals(type, contentValues); } /**