refactor(sync): перевёл журнал на map по пути и убрал цикл debounce-sync
Журнал хранится как словарь path→entry, служебные пути исключены из sync. Apply пишет файлы без записи в журнал; bootstrap не триггерит sync во время работы.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package com.github.nullptroma.wallenc.domain.datatypes
|
||||
|
||||
/** Журнал синхронизации: один актуальный [StorageSyncJournalEntry] на нормализованный путь. */
|
||||
typealias StorageSyncJournal = Map<String, StorageSyncJournalEntry>
|
||||
|
||||
object StorageSyncPaths {
|
||||
fun normalize(path: String): String = if (path.startsWith("/")) path else "/$path"
|
||||
|
||||
/**
|
||||
* Пути, которые участвуют в sync и попадают в журнал при пользовательских операциях.
|
||||
* Служебные каталоги, lock/journal/meta и файлы внутри *-enc-dir исключены.
|
||||
*/
|
||||
fun isSyncableUserPath(path: String): Boolean {
|
||||
val p = normalize(path)
|
||||
if (p == "/" || p.isBlank()) return false
|
||||
if (p == "/wallenc-yandex-system" || p.startsWith("/wallenc-yandex-system/")) return false
|
||||
if (p.contains("-enc-dir/") || p.endsWith("-enc-dir")) return false
|
||||
val name = p.substringAfterLast('/')
|
||||
if (name == "sync-journal.json" || name == "sync-lock.json") return false
|
||||
if (name.endsWith(".enc-meta") || name.endsWith(".storage-info")) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
object StorageSyncJournalMerge {
|
||||
fun merge(into: StorageSyncJournal, entries: Map<String, StorageSyncJournalEntry>): StorageSyncJournal {
|
||||
if (entries.isEmpty()) return into
|
||||
val result = into.toMutableMap()
|
||||
for ((rawPath, entry) in entries) {
|
||||
val path = StorageSyncPaths.normalize(rawPath)
|
||||
if (!StorageSyncPaths.isSyncableUserPath(path)) continue
|
||||
val normalizedEntry = entry.copy(path = path)
|
||||
val current = result[path]
|
||||
if (current == null || compareEntries(normalizedEntry, current) > 0) {
|
||||
result[path] = normalizedEntry
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun merge(into: StorageSyncJournal, entry: StorageSyncJournalEntry): StorageSyncJournal =
|
||||
merge(into, mapOf(entry.path to entry))
|
||||
|
||||
fun mergeAll(journals: Collection<StorageSyncJournal>): StorageSyncJournal {
|
||||
var acc: StorageSyncJournal = emptyMap()
|
||||
for (journal in journals) {
|
||||
acc = merge(acc, journal)
|
||||
}
|
||||
return acc
|
||||
}
|
||||
|
||||
private fun compareEntries(a: StorageSyncJournalEntry, b: StorageSyncJournalEntry): Int {
|
||||
val seqCmp = a.revision.sequence.compareTo(b.revision.sequence)
|
||||
if (seqCmp != 0) return seqCmp
|
||||
val actorCmp = a.revision.actorId.compareTo(b.revision.actorId)
|
||||
if (actorCmp != 0) return actorCmp
|
||||
return a.revision.createdAt.compareTo(b.revision.createdAt)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.github.nullptroma.wallenc.domain.interfaces
|
||||
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.DataPage
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageSyncJournalEntry
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageSyncJournal
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageSyncLock
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
@@ -40,7 +40,7 @@ interface IStorageAccessor {
|
||||
suspend fun touchFile(path: String)
|
||||
suspend fun touchDir(path: String)
|
||||
suspend fun delete(path: String)
|
||||
suspend fun openWrite(path: String): OutputStream
|
||||
suspend fun openWrite(path: String, recordSyncJournal: Boolean = true): OutputStream
|
||||
suspend fun openRead(path: String): InputStream
|
||||
suspend fun moveToTrash(path: String)
|
||||
|
||||
@@ -52,9 +52,8 @@ interface IStorageAccessor {
|
||||
suspend fun openReadSystemFile(name: String): InputStream
|
||||
suspend fun openWriteSystemFile(name: String): OutputStream
|
||||
|
||||
suspend fun readSyncJournal(): List<StorageSyncJournalEntry>
|
||||
suspend fun appendSyncJournal(entries: List<StorageSyncJournalEntry>)
|
||||
suspend fun rewriteSyncJournal(entries: List<StorageSyncJournalEntry>)
|
||||
suspend fun readSyncJournal(): StorageSyncJournal
|
||||
suspend fun putSyncJournalEntries(entries: StorageSyncJournal)
|
||||
|
||||
suspend fun readSyncLock(): StorageSyncLock?
|
||||
suspend fun tryAcquireSyncLock(holderId: String, leaseUntil: Instant): Boolean
|
||||
|
||||
Reference in New Issue
Block a user