From 3adceb6f933c5c266a496ee22b268fcf30ed559b Mon Sep 17 00:00:00 2001 From: Vyacheslav Khorkov Date: Mon, 6 May 2024 23:20:47 +0500 Subject: [PATCH] Speed up filtering by icon type --- Sources/CLI/Commands/Impact.swift | 1 + Sources/CLI/Commands/Print.swift | 1 + Sources/XTreeKit/Common/Tree/TreeFilter.swift | 10 +++++++++- Sources/XTreeKit/Managers/TreeManager.swift | 4 ++++ XTree/XTree/Modules/TreeView/TreeBuilder.swift | 11 +++-------- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Sources/CLI/Commands/Impact.swift b/Sources/CLI/Commands/Impact.swift index 66558a6..2912d0b 100644 --- a/Sources/CLI/Commands/Impact.swift +++ b/Sources/CLI/Commands/Impact.swift @@ -44,6 +44,7 @@ extension XTree.Impact { roots: treeOptions.roots, contains: treeOptions.contains, except: treeOptions.except, + exceptIcons: [], maxHeight: treeOptions.maxHeight ), sort: treeOptions.sort diff --git a/Sources/CLI/Commands/Print.swift b/Sources/CLI/Commands/Print.swift index cb2de92..5ba9839 100644 --- a/Sources/CLI/Commands/Print.swift +++ b/Sources/CLI/Commands/Print.swift @@ -34,6 +34,7 @@ extension XTree.Print { roots: treeOptions.roots, contains: treeOptions.contains, except: treeOptions.except, + exceptIcons: [], maxHeight: treeOptions.maxHeight ), sort: treeOptions.sort, diff --git a/Sources/XTreeKit/Common/Tree/TreeFilter.swift b/Sources/XTreeKit/Common/Tree/TreeFilter.swift index d339f10..c02e729 100644 --- a/Sources/XTreeKit/Common/Tree/TreeFilter.swift +++ b/Sources/XTreeKit/Common/Tree/TreeFilter.swift @@ -3,19 +3,22 @@ final class TreeFilter { _ tree: TreeNode, contains: [Regex], except: [Regex], + exceptIcons: Set, height: Int = 0, maxHeight: Int? = nil ) -> TreeNode? { - if contains.isEmpty, except.isEmpty, maxHeight == nil { return tree } + if contains.isEmpty, except.isEmpty, exceptIcons.isEmpty, maxHeight == nil { return tree } if let maxHeight = maxHeight, height >= maxHeight { return nil } guard contains.isEmpty || contains.contains(where: tree.name.contains) else { return nil } guard except.isEmpty || !except.contains(where: tree.name.contains) else { return nil } + guard !isIconExcept(tree.icon, exceptIcons: exceptIcons) else { return nil } let filteredExplicitChildren = tree.explicitChildren.compactMap { filter( $0, contains: contains, except: except, + exceptIcons: exceptIcons, height: height + 1, maxHeight: maxHeight ) @@ -34,4 +37,9 @@ final class TreeFilter { ) ) } + + private func isIconExcept(_ icon: TreeNode.Icon?, exceptIcons: Set) -> Bool { + guard !exceptIcons.isEmpty, let icon else { return false } + return exceptIcons.contains(icon.sfSymbol) + } } diff --git a/Sources/XTreeKit/Managers/TreeManager.swift b/Sources/XTreeKit/Managers/TreeManager.swift index dc9af85..09df58c 100644 --- a/Sources/XTreeKit/Managers/TreeManager.swift +++ b/Sources/XTreeKit/Managers/TreeManager.swift @@ -6,17 +6,20 @@ public struct TreeFilterOptions { public var roots: [String] public var contains: [String] public var except: [String] + public var exceptIcons: Set public var maxHeight: Int? public init( roots: [String], contains: [String], except: [String], + exceptIcons: Set, maxHeight: Int? = nil ) { self.roots = roots self.contains = contains self.except = except + self.exceptIcons = exceptIcons self.maxHeight = maxHeight } } @@ -83,6 +86,7 @@ extension TreeManager: IInternalTreeManager { tree, contains: filter.contains.map(regexBuilder.build(wildcardsPattern:)), except: filter.except.map(regexBuilder.build(wildcardsPattern:)), + exceptIcons: filter.exceptIcons, maxHeight: filter.maxHeight ) } diff --git a/XTree/XTree/Modules/TreeView/TreeBuilder.swift b/XTree/XTree/Modules/TreeView/TreeBuilder.swift index 9ebf70d..5770045 100644 --- a/XTree/XTree/Modules/TreeView/TreeBuilder.swift +++ b/XTree/XTree/Modules/TreeView/TreeBuilder.swift @@ -34,7 +34,7 @@ final class TreeBuilder: ObservableObject { guard let fileURL else { return completion(nil) } Task.detached { do { - var filter = TreeFilterOptions(roots: roots, contains: contains, except: except) + var filter = TreeFilterOptions(roots: roots, contains: contains, except: except, exceptIcons: []) let sort = Sort(rawValue: sorting.lowercased()) ?? .name let adjacentList = try await self.buildAdjacentList( path: fileURL.path, @@ -46,16 +46,11 @@ final class TreeBuilder: ObservableObject { self.userDefaultsStorage.fileURL = fileURL let icons = self.icons(adjacentList: adjacentList) - let hiddenByIconTitles = adjacentList.filter { - guard let icon = $0.value.icon else { return false } - return hiddenIcons.contains(icon.sfSymbol) - }.map(\.value.title) - let filteredAdjacentList: [String: TreeNodeContent] - if hiddenByIconTitles.isEmpty { + if hiddenIcons.isEmpty { filteredAdjacentList = adjacentList } else { - filter.except += hiddenByIconTitles + filter.exceptIcons.formUnion(hiddenIcons) filteredAdjacentList = try await self.buildAdjacentList( path: fileURL.path, filter: filter,