From: David A. Velasco Date: Wed, 11 Jul 2012 11:51:57 +0000 (+0200) Subject: Trying to improve synchronization performance with database batched operations X-Git-Tag: oc-android-1.4.3~290 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/d4f8391f509b4b211d6742db6db546b80e8277c7?ds=inline;hp=-c Trying to improve synchronization performance with database batched operations --- d4f8391f509b4b211d6742db6db546b80e8277c7 diff --git a/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java index e4c385f5..9f1d89bd 100644 --- a/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java +++ b/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java @@ -18,6 +18,7 @@ package eu.alefzero.owncloud.datamodel; +import java.util.List; import java.util.Vector; public interface DataStorageManager { @@ -32,6 +33,8 @@ public interface DataStorageManager { public boolean saveFile(OCFile file); + public void saveFiles(List files); + public Vector getDirectoryContent(OCFile f); public void removeFile(OCFile file); diff --git a/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java index 1feb424b..e1b62ef7 100644 --- a/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java +++ b/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java @@ -19,14 +19,21 @@ package eu.alefzero.owncloud.datamodel; import java.io.File; +import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.Vector; +import eu.alefzero.owncloud.db.ProviderMeta; import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta; import android.accounts.Account; import android.content.ContentProviderClient; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentValues; +import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.Environment; @@ -155,6 +162,86 @@ public class FileDataStorageManager implements DataStorageManager { return overriden; } + + @Override + public void saveFiles(List files) { + + Iterator filesIt = files.iterator(); + ArrayList operations = new ArrayList(files.size()); + OCFile file = null; + + // prepare operations to perform + while (filesIt.hasNext()) { + file = filesIt.next(); + ContentValues cv = new ContentValues(); + cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp()); + cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp()); + cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength()); + cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype()); + cv.put(ProviderTableMeta.FILE_NAME, file.getFileName()); + if (file.getParentId() != 0) + cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId()); + cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath()); + if (!file.isDirectory()) + cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath()); + cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name); + cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate()); + cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0); + + if (fileExists(file.getRemotePath())) { + OCFile tmpfile = getFileByPath(file.getRemotePath()); + file.setStoragePath(tmpfile.getStoragePath()); + if (!file.isDirectory()); + cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath()); + file.setFileId(tmpfile.getFileId()); + + operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI). + withValues(cv). + withSelection( ProviderTableMeta._ID + "=?", + new String[] { String.valueOf(file.getFileId()) }) + .build()); + + } else { + operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build()); + } + } + + // apply operations in batch + ContentProviderResult[] results = null; + try { + if (getContentResolver() != null) { + results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations); + + } else { + results = getContentProvider().applyBatch(operations); + } + + } catch (OperationApplicationException e) { + Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage()); + + } catch (RemoteException e) { + Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage()); + } + + // update new id in file objects for insertions + if (results != null) { + long newId; + for (int i=0; i updatedFiles = new Vector(resp.getResponses().length - 1); for (int i = 1; i < resp.getResponses().length; ++i) { WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath()); OCFile file = fillOCFile(we); @@ -134,12 +178,21 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { } if (getStorageManager().getFileByPath(file.getRemotePath()) != null) file.setKeepInSync(getStorageManager().getFileByPath(file.getRemotePath()).keepInSync()); - getStorageManager().saveFile(file); + //getStorageManager().saveFile(file); + updatedFiles.add(file); if (parentId == 0) parentId = file.getFileId(); } + /* Commented code for ugly performance tests + long saveDelay = System.currentTimeMillis(); + */ + getStorageManager().saveFiles(updatedFiles); // all "at once" ; trying to get a best performance in database update + /* Commented code for ugly performance tests + saveDelay = System.currentTimeMillis() - saveDelay; + Log.e(TAG, "syncing: SAVE TIME for " + uri + " contents, " + mSaveDelays[mDelaysIndex] + "ms"); + */ - // removal of old files + // removal of obsolete files Vector files = getStorageManager().getDirectoryContent( getStorageManager().getFileById(parentId)); OCFile file; @@ -162,6 +215,16 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { fetchData(getUri().toString() + newFile.getRemotePath(), syncResult, newFile.getFileId(), account); } } + + /* Commented code for ugly performance tests + mResponseDelays[mDelaysIndex] = responseDelay; + mSaveDelays[mDelaysIndex] = saveDelay; + mDelaysCount++; + mDelaysIndex++; + if (mDelaysIndex >= MAX_DELAYS) + mDelaysIndex = 0; + */ + } catch (OperationCanceledException e) {