оптимизация лишних чтений мета-файла
This commit is contained in:
@@ -11,6 +11,7 @@ import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
|
|||||||
import com.github.nullptroma.wallenc.domain.datatypes.DataPage
|
import com.github.nullptroma.wallenc.domain.datatypes.DataPage
|
||||||
import com.github.nullptroma.wallenc.domain.models.IDirectory
|
import com.github.nullptroma.wallenc.domain.models.IDirectory
|
||||||
import com.github.nullptroma.wallenc.domain.models.IFile
|
import com.github.nullptroma.wallenc.domain.models.IFile
|
||||||
|
import com.github.nullptroma.wallenc.domain.models.IMetaInfo
|
||||||
import com.github.nullptroma.wallenc.domain.models.IStorageAccessor
|
import com.github.nullptroma.wallenc.domain.models.IStorageAccessor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -96,6 +97,9 @@ class LocalStorageAccessor(
|
|||||||
callback(child)
|
callback(child)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useCallbackForSelf)
|
||||||
|
callback(dir)
|
||||||
|
|
||||||
if (maxDepth != 0) {
|
if (maxDepth != 0) {
|
||||||
val nextMaxDepth = if (maxDepth > 0) maxDepth - 1 else maxDepth
|
val nextMaxDepth = if (maxDepth > 0) maxDepth - 1 else maxDepth
|
||||||
for (child in children) {
|
for (child in children) {
|
||||||
@@ -105,9 +109,9 @@ class LocalStorageAccessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (useCallbackForSelf) {
|
||||||
if (useCallbackForSelf)
|
|
||||||
callback(dir)
|
callback(dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,13 +121,22 @@ class LocalStorageAccessor(
|
|||||||
private suspend fun scanStorage(
|
private suspend fun scanStorage(
|
||||||
baseStoragePath: String,
|
baseStoragePath: String,
|
||||||
maxDepth: Int,
|
maxDepth: Int,
|
||||||
fileCallback: suspend (LocalFile) -> Unit = {},
|
fileCallback: (suspend (File, LocalFile) -> Unit)? = null,
|
||||||
dirCallback: suspend (LocalDirectory) -> Unit = {}
|
dirCallback: (suspend (File, LocalDirectory) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
if (!checkAvailable())
|
if (!checkAvailable())
|
||||||
throw Exception("Not available")
|
throw Exception("Not available")
|
||||||
val basePath = Path(_absolutePath.pathString, baseStoragePath)
|
val basePath = Path(_absolutePath.pathString, baseStoragePath)
|
||||||
|
val workedFiles = mutableSetOf<String>()
|
||||||
|
val workedMetaFiles = mutableSetOf<String>()
|
||||||
|
var count = 0
|
||||||
scanFileSystem(basePath.toFile(), maxDepth, { file ->
|
scanFileSystem(basePath.toFile(), maxDepth, { file ->
|
||||||
|
// Если парный файл уже был обработан - скип. Это позволит не читать metaFile дважды
|
||||||
|
if(workedFiles.contains(file.absolutePath) || workedMetaFiles.contains(file.absolutePath)) {
|
||||||
|
count++
|
||||||
|
return@scanFileSystem
|
||||||
|
}
|
||||||
|
|
||||||
val filePath = Path(file.absolutePath)
|
val filePath = Path(file.absolutePath)
|
||||||
|
|
||||||
// если это файл с мета-информацией - пропустить
|
// если это файл с мета-информацией - пропустить
|
||||||
@@ -132,46 +145,60 @@ class LocalStorageAccessor(
|
|||||||
try {
|
try {
|
||||||
val reader = file.bufferedReader()
|
val reader = file.bufferedReader()
|
||||||
val meta : LocalMetaInfo = _jackson.readValue(reader)
|
val meta : LocalMetaInfo = _jackson.readValue(reader)
|
||||||
val fileInMeta = File(Path(_absolutePath.pathString, meta.path).pathString)
|
val pathString = Path(_absolutePath.pathString, meta.path).pathString
|
||||||
if (!fileInMeta.exists())
|
val originalFile = File(pathString)
|
||||||
|
if (!originalFile.exists())
|
||||||
file.delete()
|
file.delete()
|
||||||
|
|
||||||
|
// если успешно прочитано - отправить колбек и добавить обработанный файл
|
||||||
|
workedFiles.add(pathString)
|
||||||
|
workedMetaFiles.add(file.absolutePath)
|
||||||
|
if (file.isFile) {
|
||||||
|
fileCallback?.invoke(originalFile, LocalFile(meta))
|
||||||
|
} else {
|
||||||
|
dirCallback?.invoke(originalFile, LocalDirectory(meta, null))
|
||||||
|
}
|
||||||
} catch (e: JacksonException) {
|
} catch (e: JacksonException) {
|
||||||
file.delete()
|
file.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
return@scanFileSystem
|
return@scanFileSystem
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
val metaFilePath = Path(
|
||||||
|
if (file.isFile) {
|
||||||
|
file.absolutePath + META_INFO_POSTFIX
|
||||||
|
} else {
|
||||||
|
Path(file.absolutePath, META_INFO_POSTFIX).pathString
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val metaFile = metaFilePath.toFile()
|
||||||
|
val metaInfo: LocalMetaInfo
|
||||||
|
val storageFilePath = "/" + filePath.relativeTo(_absolutePath)
|
||||||
|
|
||||||
val metaFilePath = Path(
|
if (!metaFile.exists()) {
|
||||||
if (file.isFile) {
|
metaInfo = createNewLocalMetaInfo(storageFilePath, filePath.fileSize())
|
||||||
file.absolutePath + META_INFO_POSTFIX
|
_jackson.writeValue(metaFile, metaInfo)
|
||||||
} else {
|
} else {
|
||||||
Path(file.absolutePath, META_INFO_POSTFIX).pathString
|
var readMeta: LocalMetaInfo
|
||||||
|
try {
|
||||||
|
val reader = metaFile.bufferedReader()
|
||||||
|
readMeta = _jackson.readValue(reader)
|
||||||
|
} catch (e: JacksonException) {
|
||||||
|
// если файл повреждён - пересоздать
|
||||||
|
readMeta = createNewLocalMetaInfo(storageFilePath, filePath.fileSize())
|
||||||
|
_jackson.writeValue(metaFile, readMeta)
|
||||||
|
}
|
||||||
|
metaInfo = readMeta
|
||||||
}
|
}
|
||||||
)
|
|
||||||
val metaFile = metaFilePath.toFile()
|
|
||||||
val metaInfo: LocalMetaInfo
|
|
||||||
val storageFilePath = "/" + filePath.relativeTo(_absolutePath)
|
|
||||||
|
|
||||||
if (!metaFile.exists()) {
|
workedFiles.add(file.absolutePath)
|
||||||
metaInfo = createNewLocalMetaInfo(storageFilePath, filePath.fileSize())
|
workedMetaFiles.add(metaFile.absolutePath)
|
||||||
_jackson.writeValue(metaFile, metaInfo)
|
if (file.isFile) {
|
||||||
} else {
|
fileCallback?.invoke(file, LocalFile(metaInfo))
|
||||||
var readMeta: LocalMetaInfo
|
} else {
|
||||||
try {
|
dirCallback?.invoke(file, LocalDirectory(metaInfo, null))
|
||||||
val reader = metaFile.bufferedReader()
|
|
||||||
readMeta = _jackson.readValue(reader)
|
|
||||||
} catch (e: JacksonException) {
|
|
||||||
// если файл повреждён - пересоздать
|
|
||||||
readMeta = createNewLocalMetaInfo(storageFilePath, filePath.fileSize())
|
|
||||||
_jackson.writeValue(metaFile, readMeta)
|
|
||||||
}
|
}
|
||||||
metaInfo = readMeta
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.isFile) {
|
|
||||||
fileCallback(LocalFile(metaInfo))
|
|
||||||
} else {
|
|
||||||
dirCallback(LocalDirectory(metaInfo, null))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -206,8 +233,8 @@ class LocalStorageAccessor(
|
|||||||
var size = 0L
|
var size = 0L
|
||||||
var numOfFiles = 0
|
var numOfFiles = 0
|
||||||
|
|
||||||
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = {
|
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, localFile ->
|
||||||
size += it.metaInfo.size
|
size += localFile.metaInfo.size
|
||||||
numOfFiles++
|
numOfFiles++
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -220,8 +247,8 @@ class LocalStorageAccessor(
|
|||||||
return@withContext listOf()
|
return@withContext listOf()
|
||||||
|
|
||||||
val list = mutableListOf<IFile>()
|
val list = mutableListOf<IFile>()
|
||||||
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = {
|
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, localFile ->
|
||||||
list.add(it)
|
list.add(localFile)
|
||||||
})
|
})
|
||||||
return@withContext list
|
return@withContext list
|
||||||
}
|
}
|
||||||
@@ -231,8 +258,8 @@ class LocalStorageAccessor(
|
|||||||
return@withContext listOf()
|
return@withContext listOf()
|
||||||
|
|
||||||
val list = mutableListOf<IFile>()
|
val list = mutableListOf<IFile>()
|
||||||
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = {
|
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, localFile ->
|
||||||
list.add(it)
|
list.add(localFile)
|
||||||
})
|
})
|
||||||
return@withContext list
|
return@withContext list
|
||||||
}
|
}
|
||||||
@@ -243,7 +270,7 @@ class LocalStorageAccessor(
|
|||||||
|
|
||||||
val buf = mutableListOf<IFile>()
|
val buf = mutableListOf<IFile>()
|
||||||
var pageNumber = 0
|
var pageNumber = 0
|
||||||
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = {
|
scanStorage(baseStoragePath = path, maxDepth = 0, fileCallback = { _, localFile ->
|
||||||
if(buf.size == DATA_PAGE_LENGTH) {
|
if(buf.size == DATA_PAGE_LENGTH) {
|
||||||
val page = DataPage(
|
val page = DataPage(
|
||||||
list = buf.toList(),
|
list = buf.toList(),
|
||||||
@@ -256,7 +283,7 @@ class LocalStorageAccessor(
|
|||||||
emit(page)
|
emit(page)
|
||||||
buf.clear()
|
buf.clear()
|
||||||
}
|
}
|
||||||
buf.add(it)
|
buf.add(localFile)
|
||||||
})
|
})
|
||||||
// отправка последней страницы
|
// отправка последней страницы
|
||||||
val page = DataPage(
|
val page = DataPage(
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ fun LocalVaultScreen(modifier: Modifier = Modifier,
|
|||||||
Card(modifier = Modifier.clickable {
|
Card(modifier = Modifier.clickable {
|
||||||
viewModel.printAllFilesToLog(it)
|
viewModel.printAllFilesToLog(it)
|
||||||
}) {
|
}) {
|
||||||
val available = it.isAvailable.collectAsStateWithLifecycle()
|
val available by it.isAvailable.collectAsStateWithLifecycle()
|
||||||
val numOfFiles = it.isAvailable.collectAsStateWithLifecycle()
|
val numOfFiles by it.numberOfFiles.collectAsStateWithLifecycle()
|
||||||
val size = it.isAvailable.collectAsStateWithLifecycle()
|
val size by it.size.collectAsStateWithLifecycle()
|
||||||
Column {
|
Column {
|
||||||
Text(it.uuid.toString())
|
Text(it.uuid.toString())
|
||||||
Text("IsAvailable: $available")
|
Text("IsAvailable: $available")
|
||||||
|
|||||||
Reference in New Issue
Block a user