Skip to content

Commit

Permalink
Improvements to the number of instances used and memory allocation re…
Browse files Browse the repository at this point in the history
…quired for Realm DB operations:

1. Number of Realm instances was growing uncontrollably due to not explicitly being closed at the end of a series of DB Operations in some places throughout the app.
2. Instead of creating two instances of DbWrapper and configuring them for Main DB and the one used for translations and distinguishing between them using @BundleDataDb annotation, now separate DbWrapperMain and DbWrapperBundle classes are used to eliminate a possibility of using a wrong instance.
3. Removing unnecessary child coroutine scopes that was used in SyncActions.

Upping versionCode to 85
  • Loading branch information
Dima-Android committed Jul 29, 2024
1 parent ce38c78 commit e06afc0
Show file tree
Hide file tree
Showing 61 changed files with 324 additions and 359 deletions.

This file was deleted.

17 changes: 0 additions & 17 deletions app/src/main/java/org/zotero/android/api/module/GeneralModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.migration.DisableInstallInCheck
import kotlinx.serialization.json.Json
import org.zotero.android.api.annotations.BundleDataDb
import org.zotero.android.api.annotations.ForGsonWithRoundedDecimals
import org.zotero.android.api.network.InternetConnectionStatusManager
import org.zotero.android.api.network.internetConnectionStatus
import org.zotero.android.architecture.serialization.SealedClassTypeAdapter
import org.zotero.android.architecture.serialization.UriTypeAdapter
import org.zotero.android.database.DbWrapper
import org.zotero.android.files.FormattedDoubleJsonSerializer
import javax.inject.Singleton
import kotlin.jvm.internal.Reflection
Expand Down Expand Up @@ -78,19 +76,4 @@ object GeneralModule {
gsonBuilder.registerTypeAdapter(type, FormattedDoubleJsonSerializer())
return gsonBuilder.create()
}

@Provides
@Singleton
fun provideDbWrapper(
): DbWrapper {
return DbWrapper()
}

@Provides
@Singleton
@BundleDataDb
fun provideBundleDataDbWrapper(
): DbWrapper {
return DbWrapper()
}
}
33 changes: 20 additions & 13 deletions app/src/main/java/org/zotero/android/architecture/BaseViewModel2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.zotero.android.database.DbRequest
import org.zotero.android.database.DbResponseRequest
import org.zotero.android.database.DbWrapper
import org.zotero.android.database.DbWrapperMain
import timber.log.Timber

abstract class BaseViewModel2<STATE : ViewState, EFFECT : ViewEffect>(
Expand Down Expand Up @@ -111,24 +111,31 @@ abstract class BaseViewModel2<STATE : ViewState, EFFECT : ViewEffect>(
}
}

suspend fun perform(dbWrapper: DbWrapper, request: DbRequest):Result<Unit> = withContext(Dispatchers.IO) {
try {
dbWrapper.realmDbStorage.perform(request)
Result.Success(Unit)
suspend fun perform(dbWrapper: DbWrapperMain, request: DbRequest): Result<Unit> =
withContext(Dispatchers.IO) {
try {
dbWrapper.realmDbStorage.perform(request)
Result.Success(Unit)
}catch (e: Exception) {
Result.Failure(e)
}
}
suspend fun perform(dbWrapper: DbWrapper,writeRequests: List<DbRequest>):Result<Unit> = withContext(Dispatchers.IO) {
try {
dbWrapper.realmDbStorage.perform(writeRequests)
Result.Success(Unit)
}catch (e: Exception) {
Result.Failure(e)
}

suspend fun perform(dbWrapper: DbWrapperMain, writeRequests: List<DbRequest>): Result<Unit> =
withContext(Dispatchers.IO) {
try {
dbWrapper.realmDbStorage.perform(writeRequests)
Result.Success(Unit)
} catch (e: Exception) {
Result.Failure(e)
}
}

suspend inline fun<reified T: Any> perform(dbWrapper: DbWrapper, invalidateRealm: Boolean, request: DbResponseRequest<T>): Result<T> = withContext(Dispatchers.IO) {
suspend inline fun <reified T : Any> perform(
dbWrapper: DbWrapperMain,
invalidateRealm: Boolean,
request: DbResponseRequest<T>
): Result<T> = withContext(Dispatchers.IO) {
try {
Result.Success(dbWrapper.realmDbStorage.perform(request, invalidateRealm = invalidateRealm))
}catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.zotero.android.architecture.ViewEffect
import org.zotero.android.architecture.ViewState
import org.zotero.android.architecture.navigation.toolbar.data.SyncProgress
import org.zotero.android.architecture.navigation.toolbar.data.SyncProgressEventStream
import org.zotero.android.database.DbWrapper
import org.zotero.android.database.DbWrapperMain
import org.zotero.android.database.requests.ReadGroupDbRequest
import org.zotero.android.sync.SyncError
import java.util.Timer
Expand All @@ -19,7 +19,7 @@ import kotlin.concurrent.timerTask

@HiltViewModel
class SyncToolbarViewModel @Inject constructor(
private val dbWrapper: DbWrapper,
private val dbWrapperMain: DbWrapperMain,
private val syncProgressEventStream: SyncProgressEventStream,
) : BaseViewModel2<SyncToolbarViewState, SyncToolbarViewEffect>(SyncToolbarViewState()) {

Expand Down Expand Up @@ -127,7 +127,7 @@ class SyncToolbarViewModel @Inject constructor(

fun getGroupNameById(groupId: Int): String {
val group =
dbWrapper.realmDbStorage.perform(request = ReadGroupDbRequest(identifier = groupId))
dbWrapperMain.realmDbStorage.perform(request = ReadGroupDbRequest(identifier = groupId))
val groupName = group.name ?: "${groupId}"
return groupName
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import kotlinx.coroutines.async
import org.zotero.android.api.NoRedirectApi
import org.zotero.android.api.SyncApi
import org.zotero.android.api.network.CustomResult
import org.zotero.android.database.DbWrapper
import org.zotero.android.database.DbWrapperMain
import org.zotero.android.database.objects.Attachment
import org.zotero.android.database.requests.MarkFileAsDownloadedDbRequest
import org.zotero.android.files.FileStore
Expand All @@ -24,7 +24,7 @@ class AttachmentDownloader @Inject constructor(
private val syncApi: SyncApi,
private val noRedirectApi: NoRedirectApi,
private val fileStorage: FileStore,
private val dbWrapper: DbWrapper,
private val dbWrapperMain: DbWrapperMain,
private val attachmentDownloaderEventStream: AttachmentDownloaderEventStream,
private val dispatcher: CoroutineDispatcher,
private val unzipper: Unzipper,
Expand Down Expand Up @@ -287,7 +287,7 @@ class AttachmentDownloader @Inject constructor(
)
}
is CustomResult.GeneralSuccess -> {
dbWrapper.realmDbStorage.perform(
dbWrapperMain.realmDbStorage.perform(
request = MarkFileAsDownloadedDbRequest(
key = download.key,
libraryId = download.libraryId,
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/org/zotero/android/database/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ class Database {

}

fun bundledDataConfiguration(fileStorage: FileStore): RealmConfiguration {
val dbFile = fileStorage.bundledDataDbFile()
fun bundledDataConfiguration(dbFile: File): RealmConfiguration {
val builder = RealmConfiguration.Builder()
.directory(dbFile.parentFile!!)
.name(dbFile.name)
Expand Down
48 changes: 0 additions & 48 deletions app/src/main/java/org/zotero/android/database/DbWrapper.kt

This file was deleted.

21 changes: 21 additions & 0 deletions app/src/main/java/org/zotero/android/database/DbWrapperBundle.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.zotero.android.database

import io.realm.RealmConfiguration
import org.zotero.android.files.FileStore
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class DbWrapperBundle @Inject constructor(
private val fileStore: FileStore
) {

lateinit var realmDbStorage: RealmDbStorage
lateinit var config: RealmConfiguration

fun initBundleDataConfiguration() {
val dbFile = fileStore.bundledDataDbFile()
this.config = Database.bundledDataConfiguration(dbFile)
this.realmDbStorage = RealmDbStorage(config)
}
}
32 changes: 32 additions & 0 deletions app/src/main/java/org/zotero/android/database/DbWrapperMain.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.zotero.android.database

import io.realm.Realm
import io.realm.RealmConfiguration
import org.zotero.android.files.FileStore
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class DbWrapperMain @Inject constructor(
private val fileStore: FileStore
) {
lateinit var realmDbStorage: RealmDbStorage
lateinit var config: RealmConfiguration
var isInitialized = false

fun initWithMainConfiguration(userId: Long) {
val dbFile = fileStore.dbFile(userId)
this.config = Database.mainConfiguration(dbFile = dbFile)
this.realmDbStorage = RealmDbStorage(config = config)
isInitialized = true
}

fun clearDatabaseFiles() {
val realmInstance = Realm.getInstance(config)
realmInstance.removeAllChangeListeners()
realmInstance.executeTransaction {
realmInstance.deleteAll()
}
realmInstance.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class RealmDbStorage(val config: RealmConfiguration) {
val result = coordinator.perform(request = request)

if (invalidateRealm) {
coordinator.refresh()
coordinator.invalidate()
}

return result
Expand All @@ -59,13 +59,13 @@ class RealmDbStorage(val config: RealmConfiguration) {
fun perform(request: DbRequest) {
val coordinator = RealmDbCoordinator().init(config)
coordinator.perform(request = request)
coordinator.refresh()
coordinator.invalidate()
}

fun perform(requests: List<DbRequest>) {
val coordinator = RealmDbCoordinator().init(config)
coordinator.perform(requests)
coordinator.refresh()
coordinator.invalidate()
}
}

Expand Down Expand Up @@ -138,4 +138,7 @@ class RealmDbCoordinator {
realm.refresh()
}

fun invalidate() {
realm.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import org.zotero.android.architecture.ifFailure
import org.zotero.android.architecture.navigation.NavigationParamsMarshaller
import org.zotero.android.architecture.require
import org.zotero.android.database.DbRequest
import org.zotero.android.database.DbWrapper
import org.zotero.android.database.DbWrapperMain
import org.zotero.android.database.objects.AnnotationsConfig
import org.zotero.android.database.objects.FieldKeys
import org.zotero.android.database.objects.RItem
Expand Down Expand Up @@ -147,7 +147,7 @@ import javax.inject.Inject
@HiltViewModel
class PdfReaderViewModel @Inject constructor(
private val defaults: Defaults,
private val dbWrapper: DbWrapper,
private val dbWrapperMain: DbWrapperMain,
private val sessionDataEventStream: SessionDataEventStream,
private val pdfReaderCurrentThemeEventStream: PdfReaderCurrentThemeEventStream,
private val pdfReaderThemeDecider: PdfReaderThemeDecider,
Expand Down Expand Up @@ -526,7 +526,7 @@ class PdfReaderViewModel @Inject constructor(
try {
var pageStr = "0"
var results: RealmResults<RItem>? = null
dbWrapper.realmDbStorage.perform { coordinator ->
dbWrapperMain.realmDbStorage.perform { coordinator ->
pageStr = coordinator.perform(
request = ReadDocumentDataDbRequest(
attachmentKey = key,
Expand Down Expand Up @@ -804,7 +804,7 @@ class PdfReaderViewModel @Inject constructor(

viewModelScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
writeRequests = requests
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't update changed annotations")
Expand Down Expand Up @@ -2188,7 +2188,7 @@ class PdfReaderViewModel @Inject constructor(
)
viewModelScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
request = request
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't add annotations")
Expand Down Expand Up @@ -2360,7 +2360,7 @@ class PdfReaderViewModel @Inject constructor(

viewModelScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
request = request
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't remove annotations $keys")
Expand Down Expand Up @@ -2496,7 +2496,7 @@ class PdfReaderViewModel @Inject constructor(
val request = EditTagsForItemDbRequest(key = key, libraryId = viewState.library.identifier, tags = tags)
viewModelScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
request = request
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't set tags $key")
Expand Down Expand Up @@ -2556,7 +2556,7 @@ class PdfReaderViewModel @Inject constructor(

viewModelScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
request = request
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't update annotation $key")
Expand All @@ -2577,7 +2577,7 @@ class PdfReaderViewModel @Inject constructor(
)
ZoteroApplication.instance.applicationScope.launch {
perform(
dbWrapper = dbWrapper,
dbWrapper = dbWrapperMain,
request = request
).ifFailure {
Timber.e(it, "PDFReaderViewModel: can't store page")
Expand Down
Loading

0 comments on commit e06afc0

Please sign in to comment.