Skip to content

Commit

Permalink
Improve filterDistinctRoots performance
Browse files Browse the repository at this point in the history
By using a cheap path length comparison we can return faster from within `isAncestorOf` in some cases.
  • Loading branch information
d4rken committed Nov 28, 2024
1 parent aa8edec commit c396768
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package eu.darken.sdmse.common.files

import eu.darken.sdmse.common.debug.logging.Logging.Priority.VERBOSE
import eu.darken.sdmse.common.debug.logging.log
import kotlinx.coroutines.flow.Flow
import okio.FileHandle

Expand Down Expand Up @@ -91,8 +93,14 @@ fun APathLookup<*>.removePrefix(prefix: APath, overlap: Int = 0) =
lookedUp.removePrefix(prefix, overlap)

fun Collection<APathLookup<*>>.filterDistinctRoots(): Set<APathLookup<*>> {
log(VERBOSE) { "Creating lookup map..." }
val lookupMap = this.associateBy { it.lookedUp }
return lookupMap.keys.filterDistinctRoots().map { lookupMap.getValue(it) }.toSet()
log(VERBOSE) { "Lookup map created with ${lookupMap.size} entries, now filtering..." }
return lookupMap.keys
.filterDistinctRoots()
.map { lookupMap.getValue(it) }
.toSet()
.also { log(VERBOSE) { "After filtering we got ${it.size} distinct roots" } }
}

val APathLookup<*>.extension: String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ fun LocalPath.performLookupExtended(
}

fun LocalPath.isAncestorOf(child: LocalPath): Boolean {
val parentPath = this.asFile().absolutePath
val childPath = child.asFile().absolutePath
val parentPath = this.asFile().path
val childPath = child.asFile().path

return when (parentPath) {
childPath -> false
File.separator -> childPath.startsWith(parentPath)
else -> childPath.startsWith(parentPath + File.separator)
return when {
parentPath.length >= childPath.length -> false
!childPath.startsWith(parentPath) -> false
parentPath == File.separator -> true
else -> childPath[parentPath.length] == File.separatorChar
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,18 @@ class APathLookupExtensionTest : BaseTest() {
lookup4
)
}

@Test fun `filterDistinctRoots performance`() {
val targets = mutableSetOf<LocalPathLookup>()
(1..8000).forEach {
LocalPathLookup(
lookedUp = LocalPath.build("parentA", "parentB", "file$it"),
fileType = FileType.FILE,
size = 0,
modifiedAt = Instant.EPOCH,
target = null,
).run { targets.add(this) }
}
targets.filterDistinctRoots().size shouldBe 8000
}
}

0 comments on commit c396768

Please sign in to comment.