perf: 合并数据库

This commit is contained in:
lisonge 2023-10-08 14:39:06 +08:00
parent 8074175489
commit deb394ce38
17 changed files with 41 additions and 736 deletions

View File

@ -31,12 +31,9 @@ android {
useSupportLibrary = true
}
javaCompileOptions {
annotationProcessorOptions {
arguments += mapOf(
"room.schemaLocation" to "$projectDir/schemas", "room.incremental" to "true"
)
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("room.incremental", "true")
}
val nowTime = System.currentTimeMillis()
buildConfigField("Long", "BUILD_TIME", jsonStringOf(nowTime) + "L")
@ -117,10 +114,6 @@ android {
}
}
kapt {
correctErrorTypes = true
}
dependencies {
implementation(project(mapOf("path" to ":selector")))

View File

@ -1,264 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "f3feda76127233f3416d7570fca1615f",
"entities": [
{
"tableName": "subs_item",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `ctime` INTEGER NOT NULL, `mtime` INTEGER NOT NULL, `enable` INTEGER NOT NULL, `name` TEXT NOT NULL, `update_url` TEXT NOT NULL, `version` INTEGER NOT NULL, `file_path` TEXT NOT NULL, `index` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ctime",
"columnName": "ctime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mtime",
"columnName": "mtime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "enable",
"columnName": "enable",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "updateUrl",
"columnName": "update_url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "version",
"columnName": "version",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "filePath",
"columnName": "file_path",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "index",
"columnName": "index",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_subs_item_update_url",
"unique": true,
"columnNames": [
"update_url"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_subs_item_update_url` ON `${TABLE_NAME}` (`update_url`)"
}
],
"foreignKeys": []
},
{
"tableName": "subs_config",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `ctime` INTEGER NOT NULL, `mtime` INTEGER NOT NULL, `type` INTEGER NOT NULL, `enable` INTEGER NOT NULL, `subs_item_id` INTEGER NOT NULL, `app_id` TEXT NOT NULL, `group_key` INTEGER NOT NULL, `rule_key` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ctime",
"columnName": "ctime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mtime",
"columnName": "mtime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "enable",
"columnName": "enable",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "subsItemId",
"columnName": "subs_item_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "appId",
"columnName": "app_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "groupKey",
"columnName": "group_key",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ruleKey",
"columnName": "rule_key",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "snapshot",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `app_id` TEXT, `activity_id` TEXT, `app_name` TEXT, `app_version_code` INTEGER, `app_version_name` TEXT, `screen_height` INTEGER NOT NULL, `screen_width` INTEGER NOT NULL, `is_landscape` INTEGER NOT NULL, `device` TEXT NOT NULL, `model` TEXT NOT NULL, `manufacturer` TEXT NOT NULL, `brand` TEXT NOT NULL, `sdk_int` INTEGER NOT NULL, `release` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "appId",
"columnName": "app_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "activityId",
"columnName": "activity_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "appName",
"columnName": "app_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "appVersionCode",
"columnName": "app_version_code",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "appVersionName",
"columnName": "app_version_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "screenHeight",
"columnName": "screen_height",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "screenWidth",
"columnName": "screen_width",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isLandscape",
"columnName": "is_landscape",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "device",
"columnName": "device",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "model",
"columnName": "model",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "manufacturer",
"columnName": "manufacturer",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "brand",
"columnName": "brand",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sdkInt",
"columnName": "sdk_int",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "release",
"columnName": "release",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f3feda76127233f3416d7570fca1615f')"
]
}
}

View File

@ -1,64 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "81719a0dbd7e0ef535884794b5eec49e",
"entities": [
{
"tableName": "trigger_log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `ctime` INTEGER NOT NULL, `mtime` INTEGER NOT NULL, `app_id` TEXT, `activity_id` TEXT, `selector` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ctime",
"columnName": "ctime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mtime",
"columnName": "mtime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "appId",
"columnName": "app_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "activityId",
"columnName": "activity_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "selector",
"columnName": "selector",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '81719a0dbd7e0ef535884794b5eec49e')"
]
}
}

View File

@ -1,124 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "296a7b78252c48246f24767e66441c22",
"entities": [
{
"tableName": "snapshot",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `app_id` TEXT, `activity_id` TEXT, `app_name` TEXT, `app_version_code` INTEGER, `app_version_name` TEXT, `screen_height` INTEGER NOT NULL, `screen_width` INTEGER NOT NULL, `is_landscape` INTEGER NOT NULL, `device` TEXT NOT NULL, `model` TEXT NOT NULL, `manufacturer` TEXT NOT NULL, `brand` TEXT NOT NULL, `sdk_int` INTEGER NOT NULL, `release` TEXT NOT NULL, `_1` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "appId",
"columnName": "app_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "activityId",
"columnName": "activity_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "appName",
"columnName": "app_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "appVersionCode",
"columnName": "app_version_code",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "appVersionName",
"columnName": "app_version_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "screenHeight",
"columnName": "screen_height",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "screenWidth",
"columnName": "screen_width",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isLandscape",
"columnName": "is_landscape",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "device",
"columnName": "device",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "model",
"columnName": "model",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "manufacturer",
"columnName": "manufacturer",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "brand",
"columnName": "brand",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sdkInt",
"columnName": "sdk_int",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "release",
"columnName": "release",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "nodes",
"columnName": "_1",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '296a7b78252c48246f24767e66441c22')"
]
}
}

View File

@ -1,70 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "5ad1f90d8f2852410fde46463bf24322",
"entities": [
{
"tableName": "subs_config",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `mtime` INTEGER NOT NULL, `type` INTEGER NOT NULL, `enable` INTEGER NOT NULL, `subs_item_id` INTEGER NOT NULL, `app_id` TEXT NOT NULL, `group_key` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mtime",
"columnName": "mtime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "enable",
"columnName": "enable",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "subsItemId",
"columnName": "subs_item_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "appId",
"columnName": "app_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "groupKey",
"columnName": "group_key",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5ad1f90d8f2852410fde46463bf24322')"
]
}
}

View File

@ -1,88 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "b51332e64931ac0cef5774cb5df5b703",
"entities": [
{
"tableName": "subs_item",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `mtime` INTEGER NOT NULL, `enable` INTEGER NOT NULL, `enable_update` INTEGER NOT NULL, `order` INTEGER NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `version` INTEGER NOT NULL, `update_url` TEXT NOT NULL, `support_url` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mtime",
"columnName": "mtime",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "enable",
"columnName": "enable",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "enableUpdate",
"columnName": "enable_update",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "order",
"columnName": "order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "version",
"columnName": "version",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateUrl",
"columnName": "update_url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "supportUrl",
"columnName": "support_url",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b51332e64931ac0cef5774cb5df5b703')"
]
}
}

View File

@ -1,34 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "e565cbca157f8ba6cecb6e7cd7cc6304",
"entities": [
{
"tableName": "trigger_log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e565cbca157f8ba6cecb6e7cd7cc6304')"
]
}
}

View File

@ -0,0 +1,19 @@
package li.songe.gkd.db
import androidx.room.Database
import androidx.room.RoomDatabase
import li.songe.gkd.data.ClickLog
import li.songe.gkd.data.Snapshot
import li.songe.gkd.data.SubsConfig
import li.songe.gkd.data.SubsItem
@Database(
version = 1,
entities = [SubsItem::class, Snapshot::class, SubsConfig::class, ClickLog::class],
)
abstract class AppDb : RoomDatabase() {
abstract fun subsItemDao(): SubsItem.SubsItemDao
abstract fun snapshotDao(): Snapshot.SnapshotDao
abstract fun subsConfigDao(): SubsConfig.SubsConfigDao
abstract fun clickLogDao(): ClickLog.TriggerLogDao
}

View File

@ -1,13 +0,0 @@
package li.songe.gkd.db
import androidx.room.Database
import androidx.room.RoomDatabase
import li.songe.gkd.data.ClickLog
@Database(
version = 1,
entities = [ClickLog::class],
)
abstract class ClickLogDb : RoomDatabase() {
abstract fun clickLogDao(): ClickLog.TriggerLogDao
}

View File

@ -18,26 +18,19 @@ import li.songe.gkd.util.FolderExt
import li.songe.gkd.util.Singleton
import li.songe.gkd.util.isMainProcess
import li.songe.gkd.util.launchTry
import java.io.File
object DbSet {
private fun <T : RoomDatabase> getDb(
klass: Class<T>, name: String,
): RoomDatabase.Builder<T> {
return Room.databaseBuilder(
app, klass, FolderExt.dbFolder.absolutePath.plus("/${name}.db")
private val appDb by lazy {
Room.databaseBuilder(
app, AppDb::class.java, File(FolderExt.dbFolder, "gkd.db").absolutePath
).fallbackToDestructiveMigration().enableMultiInstanceInvalidation()
.addCallback(createCallback()).build()
}
private val snapshotDb by lazy { getDb(SnapshotDb::class.java, "snapshot").build() }
private val subsConfigDb by lazy { getDb(SubsConfigDb::class.java, "subsConfig").build() }
private val subsItemDb by lazy {
getDb(SubsItemDb::class.java, "subsItem").addCallback(createCallback()).build()
}
val clickLogDb by lazy { getDb(ClickLogDb::class.java, "clickLog").build() }
val subsItemDao by lazy { subsItemDb.subsItemDao() }
val subsConfigDao by lazy { subsConfigDb.subsConfigDao() }
val snapshotDao by lazy { snapshotDb.snapshotDao() }
val subsItemDao by lazy { appDb.subsItemDao() }
val subsConfigDao by lazy { appDb.subsConfigDao() }
val snapshotDao by lazy { appDb.snapshotDao() }
val clickLogDao by lazy { appDb.clickLogDao() }
private fun createCallback(): RoomDatabase.Callback {
return object : RoomDatabase.Callback() {
@ -46,8 +39,7 @@ object DbSet {
if (!isMainProcess) return
appScope.launchTry(Dispatchers.IO) {
val defaultSubsItem = SubsItem(
id = 0,
order = 0,
id = 0, order = 0,
updateUrl = "https://registry.npmmirror.com/@gkd-kit/subscription/latest/files",
mtime = 0
)
@ -56,12 +48,11 @@ object DbSet {
SQLiteDatabase.CONFLICT_IGNORE,
defaultSubsItem.toContentValues()
)
if (defaultSubsItem.updateUrl == null) return@launchTry
try {
val s = System.currentTimeMillis()
val newSubsRaw = withTimeout(3000) {
SubscriptionRaw.parse(
Singleton.client.get(defaultSubsItem.updateUrl).bodyAsText()
Singleton.client.get(defaultSubsItem.updateUrl!!).bodyAsText()
)
}
delay(1500 - (System.currentTimeMillis() - s))

View File

@ -1,13 +0,0 @@
package li.songe.gkd.db
import androidx.room.Database
import androidx.room.RoomDatabase
import li.songe.gkd.data.Snapshot
@Database(
version = 1,
entities = [Snapshot::class],
)
abstract class SnapshotDb: RoomDatabase() {
abstract fun snapshotDao(): Snapshot.SnapshotDao
}

View File

@ -1,13 +0,0 @@
package li.songe.gkd.db
import androidx.room.Database
import androidx.room.RoomDatabase
import li.songe.gkd.data.SubsConfig
@Database(
version = 1,
entities = [SubsConfig::class],
)
abstract class SubsConfigDb: RoomDatabase() {
abstract fun subsConfigDao(): SubsConfig.SubsConfigDao
}

View File

@ -1,13 +0,0 @@
package li.songe.gkd.db
import androidx.room.Database
import androidx.room.RoomDatabase
import li.songe.gkd.data.SubsItem
@Database(
version = 1,
entities = [SubsItem::class],
)
abstract class SubsItemDb: RoomDatabase() {
abstract fun subsItemDao(): SubsItem.SubsItemDao
}

View File

@ -173,7 +173,7 @@ class GkdAbService : CompositionAbService({
ruleIndex = rule.index,
ruleKey = rule.key
)
DbSet.clickLogDb.clickLogDao().insert(clickLog)
DbSet.clickLogDao.insert(clickLog)
increaseClickCount()
}
}

View File

@ -138,9 +138,7 @@ fun ClickLogPage() {
Text(text = "删除", modifier = Modifier
.clickable(onClick = scope.launchAsFn {
previewClickLog = null
DbSet.clickLogDb
.clickLogDao()
.delete(previewTriggerLogVal)
DbSet.clickLogDao.delete(previewTriggerLogVal)
})
.fillMaxWidth()
.padding(10.dp))

View File

@ -14,11 +14,11 @@ import javax.inject.Inject
@HiltViewModel
class ClickLogVm @Inject constructor() : ViewModel() {
val clickLogsFlow = DbSet.clickLogDb.clickLogDao().query()
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
val clickLogsFlow =
DbSet.clickLogDao.query().stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
val clickLogCountFlow = DbSet.clickLogDb.clickLogDao().count()
.stateIn(viewModelScope, SharingStarted.Eagerly, 0)
val clickLogCountFlow =
DbSet.clickLogDao.count().stateIn(viewModelScope, SharingStarted.Eagerly, 0)
fun getGroup(clickLog: ClickLog): SubscriptionRaw.GroupRaw? {
val subsItem = subsItemsFlow.value.find { s -> s.id == clickLog.subsId } ?: return null

View File

@ -15,8 +15,8 @@ import javax.inject.Inject
@HiltViewModel
class ControlVm @Inject constructor() : ViewModel() {
private val latestRecordFlow = DbSet.clickLogDb.clickLogDao().queryLatest()
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
private val latestRecordFlow =
DbSet.clickLogDao.queryLatest().stateIn(viewModelScope, SharingStarted.Eagerly, null)
val latestRecordDescFlow = combine(
latestRecordFlow, subsIdToRawFlow, appInfoCacheFlow