Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve av. offline performance #4354

Merged
merged 9 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ ownCloud admins and users.
* Enhancement - Improvements in Manage Accounts view: [#4148](https://github.com/owncloud/android/issues/4148)
* Enhancement - New setting for manual removal of local storage: [#4174](https://github.com/owncloud/android/issues/4174)
* Enhancement - New setting for automatic removal of local files: [#4175](https://github.com/owncloud/android/issues/4175)
* Enhancement - Avoid unnecessary requests when an av. offline folder is refreshed: [#4197](https://github.com/owncloud/android/issues/4197)
* Enhancement - Unit tests for repository classes - Part 1: [#4232](https://github.com/owncloud/android/issues/4232)
* Enhancement - Add a warning in http connections: [#4284](https://github.com/owncloud/android/issues/4284)
* Enhancement - Make dialog more Android-alike: [#4303](https://github.com/owncloud/android/issues/4303)
Expand Down Expand Up @@ -144,6 +145,15 @@ ownCloud admins and users.
https://github.com/owncloud/android/issues/4175
https://github.com/owncloud/android/pull/4320

* Enhancement - Avoid unnecessary requests when an av. offline folder is refreshed: [#4197](https://github.com/owncloud/android/issues/4197)

The available offline folders will only be refreshed when their eTag from the
server and the corresponding one of the local database are different, avoiding
sending unnecessary request.

https://github.com/owncloud/android/issues/4197
https://github.com/owncloud/android/pull/4354

* Enhancement - Unit tests for repository classes - Part 1: [#4232](https://github.com/owncloud/android/issues/4232)

Unit tests for OCAppRegistryRepository, OCAuthenticationRepository and
Expand Down
7 changes: 7 additions & 0 deletions changelog/unreleased/4354
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Avoid unnecessary requests when an av. offline folder is refreshed

The available offline folders will only be refreshed when their eTag from the server and the corresponding one of the local database are different,
avoiding sending unnecessary request.

https://github.com/owncloud/android/issues/4197
https://github.com/owncloud/android/pull/4354
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ class ReleaseNotesViewModel(
subtitle = R.string.release_notes_4_3_0_subtitle_display_name_truncation,
type = ReleaseNoteType.BUGFIX
),
ReleaseNote(
title = R.string.release_notes_4_3_0_title_improve_available_offline_performance,
subtitle = R.string.release_notes_4_3_0_subtitle_improve_available_offline_performance,
type = ReleaseNoteType.ENHANCEMENT
),
)
}
}

2 changes: 2 additions & 0 deletions owncloudApp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@
<string name="release_notes_4_3_0_subtitle_password_generator">Passwords for public links can be now generated via a new generator in Infinite Scale accounts</string>
<string name="release_notes_4_3_0_title_display_name_truncation">Resolved the bug where long display names were truncated incorrectly</string>
<string name="release_notes_4_3_0_subtitle_display_name_truncation">Display names are now properly truncated in the middle with ellipsis (…) to maintain readability</string>
<string name="release_notes_4_3_0_title_improve_available_offline_performance">Improvements in available offline performance</string>
<string name="release_notes_4_3_0_subtitle_improve_available_offline_performance">Files contained in an available offline folder will be refreshed only if they have been modified</string>

<!-- Open in web -->
<string name="ic_action_open_in_web">Open in web</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface LocalFileDataSource {
fun getFilesWithLastUsageOlderThanGivenTime(milliseconds: Long): List<OCFile>
fun moveFile(sourceFile: OCFile, targetFolder: OCFile, finalRemotePath: String, finalStoragePath: String)
fun copyFile(sourceFile: OCFile, targetFolder: OCFile, finalRemotePath: String, remoteId: String, replace: Boolean?)
fun saveFilesInFolderAndReturnThem(listOfFiles: List<OCFile>, folder: OCFile): List<OCFile>
fun saveFilesInFolderAndReturnTheFilesThatChanged(listOfFiles: List<OCFile>, folder: OCFile): List<OCFile>
fun saveFile(file: OCFile)
fun saveConflict(fileId: Long, eTagInConflict: String)
fun cleanConflict(fileId: Long)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ class OCLocalFileDataSource(
)
}

override fun saveFilesInFolderAndReturnThem(listOfFiles: List<OCFile>, folder: OCFile): List<OCFile> {
override fun saveFilesInFolderAndReturnTheFilesThatChanged(listOfFiles: List<OCFile>, folder: OCFile): List<OCFile> {
// TODO: If it is root, add 0 as parent Id
val folderContent = fileDao.insertFilesInFolderAndReturnThem(
val folderContent = fileDao.insertFilesInFolderAndReturnTheFilesThatChanged(
folder = folder.toEntity(),
folderContent = listOfFiles.map { it.toEntity() }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ interface FileDao {
* return folder content
*/
@Transaction
fun insertFilesInFolderAndReturnThem(
fun insertFilesInFolderAndReturnTheFilesThatChanged(
folder: OCFileEntity,
folderContent: List<OCFileEntity>,
): List<OCFileEntity> {
Expand All @@ -223,7 +223,13 @@ interface FileDao {
availableOfflineStatus = getNewAvailableOfflineStatus(folder.availableOfflineStatus, fileToInsert.availableOfflineStatus)
})
}
return getFolderContent(folderId)
val folderContentLocal = getFolderContent(folderId)

return folderContentLocal.filter { localFile ->
folderContent.any { changedFile ->
localFile.remoteId == changedFile.remoteId
}
}
}

@Transaction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class OCFileRepository(
accountName = parentFolder.owner,
spaceWebDavUrl = spaceWebDavUrl,
).also {
localFileDataSource.saveFilesInFolderAndReturnThem(
localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(
folder = parentFolder,
listOfFiles = listOf(
OCFile(
Expand Down Expand Up @@ -424,7 +424,7 @@ class OCFileRepository(
if (remoteFolder.isAvailableOffline) AVAILABLE_OFFLINE_PARENT else NOT_AVAILABLE_OFFLINE

})
} else {
} else if (localChildToSync.etag != remoteChild.etag || localChildToSync.localModificationTimestamp > remoteChild.lastSyncDateForData!!) {
// File exists in the database, we need to check several stuff.
folderContentUpdated.add(
remoteChild.apply {
Expand Down Expand Up @@ -461,7 +461,7 @@ class OCFileRepository(
remoteFolder.etagInConflict = null
}

return localFileDataSource.saveFilesInFolderAndReturnThem(
return localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(
folder = remoteFolder,
listOfFiles = folderContentUpdated
)
Expand Down Expand Up @@ -598,7 +598,7 @@ class OCFileRepository(
private fun deleteLocalFile(ocFile: OCFile, onlyFromLocalStorage: Boolean) {
localStorageProvider.deleteLocalFile(ocFile)
if (onlyFromLocalStorage) {
localFileDataSource.saveFile(ocFile.copy(storagePath = null, etagInConflict = null, lastUsage = null))
localFileDataSource.saveFile(ocFile.copy(storagePath = null, etagInConflict = null, lastUsage = null, etag = null))
} else {
localFileDataSource.deleteFile(ocFile.id!!)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
* @author Abel García de Prada
* @author Aitor Ballesteros Pavón
* @author Juan Carlos Garrote Gascón
* @author Aitor Ballesteros Pavón
*
* Copyright (C) 2023 ownCloud GmbH.
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
Expand Down Expand Up @@ -524,25 +525,25 @@ class OCLocalFileDataSourceTest {
}

@Test
fun `saveFilesInFolderAndReturnThem saves a list of OCFile and returns them`() {
every { fileDao.insertFilesInFolderAndReturnThem(OC_FOLDER_ENTITY, listOf(OC_FILE_ENTITY)) } returns listOf(OC_FILE_ENTITY)
fun `saveFilesInFolderAndReturnTheFilesThatChanged saves a list of OCFile and returns only the changed files`() {
every { fileDao.insertFilesInFolderAndReturnTheFilesThatChanged(OC_FOLDER_ENTITY, listOf(OC_FILE_ENTITY)) } returns listOf(OC_FILE_ENTITY)

val result = ocLocalFileDataSource.saveFilesInFolderAndReturnThem(listOf(OC_FILE), OC_FOLDER)
val result = ocLocalFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(listOf(OC_FILE), OC_FOLDER)

assertEquals(listOf(OC_FILE), result)

verify(exactly = 1) { fileDao.insertFilesInFolderAndReturnThem(OC_FOLDER_ENTITY, listOf(OC_FILE_ENTITY)) }
verify(exactly = 1) { fileDao.insertFilesInFolderAndReturnTheFilesThatChanged(OC_FOLDER_ENTITY, listOf(OC_FILE_ENTITY)) }
}

@Test
fun `saveFilesInFolderAndReturnThem returns an empty list when DAO returns an empty list`() {
every { fileDao.insertFilesInFolderAndReturnThem(OC_FOLDER_ENTITY, emptyList()) } returns emptyList()
fun `saveFilesInFolderAndReturnTheFilesThatChanged returns an empty list when DAO returns an empty list`() {
every { fileDao.insertFilesInFolderAndReturnTheFilesThatChanged(OC_FOLDER_ENTITY, emptyList()) } returns emptyList()

val result = ocLocalFileDataSource.saveFilesInFolderAndReturnThem(emptyList(), OC_FOLDER)
val result = ocLocalFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(emptyList(), OC_FOLDER)

assertEquals(emptyList<OCFile>(), result)

verify(exactly = 1) { fileDao.insertFilesInFolderAndReturnThem(OC_FOLDER_ENTITY, emptyList()) }
verify(exactly = 1) { fileDao.insertFilesInFolderAndReturnTheFilesThatChanged(OC_FOLDER_ENTITY, emptyList()) }
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class OCFileRepositoryTest {

verify(exactly = 1) {
remoteFileDataSource.createFolder(any(), false, false, OC_ACCOUNT_NAME, null)
localFileDataSource.saveFilesInFolderAndReturnThem(any(), OC_FOLDER)
localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(any(), OC_FOLDER)
}
}

Expand All @@ -93,7 +93,7 @@ class OCFileRepositoryTest {
remoteFileDataSource.createFolder(any(), false, false, OC_ACCOUNT_NAME, null)
}
verify(exactly = 0) {
localFileDataSource.saveFilesInFolderAndReturnThem(any(), OC_FOLDER)
localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(any(), OC_FOLDER)
}
}

Expand Down Expand Up @@ -302,7 +302,7 @@ class OCFileRepositoryTest {

verify(exactly = 1) {
remoteFileDataSource.refreshFolder(folderToFetch.remotePath, OC_ACCOUNT_NAME)
localFileDataSource.saveFilesInFolderAndReturnThem(
localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(
listOfFiles = listOfFilesRetrieved.drop(1),
folder = listOfFilesRetrieved.first()
)
Expand All @@ -321,7 +321,7 @@ class OCFileRepositoryTest {
remoteFileDataSource.refreshFolder(OC_FOLDER.remotePath, OC_ACCOUNT_NAME)
}
verify(exactly = 0) {
localFileDataSource.saveFilesInFolderAndReturnThem(any(), any())
localFileDataSource.saveFilesInFolderAndReturnTheFilesThatChanged(any(), any())
}
}

Expand Down
Loading