diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt index 85109337..4c5b0ad5 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt @@ -34,11 +34,58 @@ import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.PermissionsActivity import com.etesync.syncadapter.utils.NotificationUtils import okhttp3.HttpUrl +import java.lang.Math.abs import java.util.* import java.util.logging.Level //import com.android.vending.billing.IInAppBillingService; +typealias JournalList = List> + +class CachedJournalFetcher { + private val cache: HashMap> = HashMap() + + private fun fetchJournals(journalsManager: JournalManager, settings: AccountSettings, serviceType: CollectionInfo.Type): JournalList { + val journals = LinkedList>() + + for (journal in journalsManager.list()) { + val crypto: Crypto.CryptoManager + if (journal.key != null) { + crypto = Crypto.CryptoManager(journal.version, settings.keyPair!!, journal.key) + } else { + crypto = Crypto.CryptoManager(journal.version, settings.password(), journal.uid!!) + } + + journal.verify(crypto) + + val info = CollectionInfo.fromJson(journal.getContent(crypto)) + info.updateFromJournal(journal) + + journals.add(Pair(journal, info)) + } + + return journals; + } + + fun list(journalsManager: JournalManager, settings: AccountSettings, serviceType: CollectionInfo.Type): JournalList { + val cacheAge = 5 * 1000 // 5 seconds - it's just a hack for burst fetching + val now = System.currentTimeMillis() + + val journals: JournalList + synchronized (cache) { + val cached = cache.get(settings.account.name) + if ((cached != null) && (abs(now - cached.first!!) <= cacheAge)) { + journals = cached.second!! + } else { + journals = fetchJournals(journalsManager, settings, serviceType) + cache.set(settings.account.name, Pair(System.currentTimeMillis(), journals)) + } + } + + return journals.filter { it.second?.type == serviceType } + } +} + abstract class SyncAdapterService : Service() { protected abstract fun syncAdapter(): AbstractThreadedSyncAdapter @@ -47,7 +94,6 @@ abstract class SyncAdapterService : Service() { return syncAdapter().syncAdapterBinder } - abstract class SyncAdapter(context: Context) : AbstractThreadedSyncAdapter(context, false) { abstract val syncErrorTitle: Int abstract val notificationManager: SyncNotification @@ -160,27 +206,10 @@ abstract class SyncAdapterService : Service() { val journalsManager = JournalManager(httpClient.okHttpClient, HttpUrl.get(settings.uri!!)!!) - val journals = LinkedList>() - - for (journal in journalsManager.list()) { - val crypto: Crypto.CryptoManager - if (journal.key != null) { - crypto = Crypto.CryptoManager(journal.version, settings.keyPair!!, journal.key) - } else { - crypto = Crypto.CryptoManager(journal.version, settings.password(), journal.uid!!) - } - - journal.verify(crypto) - - val info = CollectionInfo.fromJson(journal.getContent(crypto)) - info.updateFromJournal(journal) - - if (info.type == serviceType) { - journals.add(Pair(journal, info)) - } - } + var journals = journalFetcher.list(journalsManager, settings, serviceType) if (journals.isEmpty()) { + journals = LinkedList() try { val info = CollectionInfo.defaultForServiceType(serviceType) val uid = JournalManager.Journal.genUid() @@ -232,4 +261,8 @@ abstract class SyncAdapterService : Service() { } } } + + companion object { + val journalFetcher = CachedJournalFetcher() + } }