1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-11 13:34:23 +00:00

Greatly improve scanning speed

This commit is contained in:
Tw93
2025-10-17 21:19:05 +08:00
parent 43616666db
commit 640499d302
4 changed files with 195 additions and 42 deletions

View File

@@ -19,7 +19,7 @@ source "$LIB_DIR/common.sh"
# Constants
readonly CACHE_DIR="${HOME}/.config/mole/cache"
readonly TEMP_PREFIX="/tmp/mole_analyze_$$"
readonly MIN_LARGE_FILE_SIZE="1000000000" # 1GB
readonly MIN_LARGE_FILE_SIZE="500000000" # 500MB (more sensitive)
readonly MIN_MEDIUM_FILE_SIZE="100000000" # 100MB
# Emoji badges for list displays only
@@ -105,9 +105,9 @@ scan_directories() {
# Check if we can use parallel processing
if command -v xargs &> /dev/null && [[ $depth -eq 1 ]]; then
# Fast parallel scan for depth 1
# Fast parallel scan for depth 1 (increased parallelism)
find "$target_path" -mindepth 1 -maxdepth 1 -type d -print0 2> /dev/null |
xargs -0 -P 4 -I {} du -sk {} 2> /dev/null |
xargs -0 -P 8 -I {} du -sk {} 2> /dev/null |
sort -rn |
while IFS=$'\t' read -r size path; do
echo "$((size * 1024))|$path"
@@ -1375,9 +1375,12 @@ scan_directory_contents_fast() {
# Auto-detect optimal parallel jobs using common function
local num_jobs
num_jobs=$(get_optimal_parallel_jobs "io")
# Cap at reasonable limits for I/O operations
[[ $num_jobs -gt 24 ]] && num_jobs=24
[[ $num_jobs -lt 12 ]] && num_jobs=12
# Keep within practical limits to avoid IO thrashing on small machines
if [[ $num_jobs -gt 32 ]]; then
num_jobs=32
elif [[ $num_jobs -lt 4 ]]; then
num_jobs=4
fi
local temp_dirs="$output_file.dirs"
local temp_files="$output_file.files"
@@ -1448,7 +1451,7 @@ scan_directory_contents_fast() {
fi
[[ ${#spinner[@]} -eq 0 ]] && spinner=('|' '/' '-' '\\')
local i=0
local max_wait=30 # Reduced to 30 seconds (fast fail)
local max_wait=45 # Balanced timeout (fast but not too aggressive)
local elapsed=0
local tick=0
local spin_len=${#spinner[@]}
@@ -1563,12 +1566,19 @@ show_volumes_overview() {
[[ -d "$HOME/Library" ]] && echo "700|$HOME/Library|User Library"
[[ -d "/Library" ]] && echo "600|/Library|System Library"
# External volumes (if any)
# External volumes (filter obvious system mounts)
if [[ -d "/Volumes" ]]; then
local vol_priority=500
find /Volumes -mindepth 1 -maxdepth 1 -type d 2> /dev/null | while IFS= read -r vol; do
local vol_name
vol_name=$(basename "$vol")
# Skip internal/system volumes and dmg helper mounts, but keep user disks
case "$vol_name" in
"MacintoshHD" | "Macintosh HD" | "Macintosh HD - Data") continue ;;
dmg.* | *.dmg) continue ;;
esac
echo "$((vol_priority))|$vol|Volume: $vol_name"
((vol_priority--))
done

View File

@@ -60,6 +60,44 @@ get_app_last_used() {
fi
}
# Compact the "last used" descriptor for aligned summaries
format_last_used_summary() {
local value="$1"
case "$value" in
"" | "Unknown")
echo "Unknown"
return 0
;;
"Never" | "Recent" | "Today" | "Yesterday" | "This year" | "Old")
echo "$value"
return 0
;;
esac
if [[ $value =~ ^([0-9]+)[[:space:]]+days?\ ago$ ]]; then
echo "${BASH_REMATCH[1]}d ago"
return 0
fi
if [[ $value =~ ^([0-9]+)[[:space:]]+weeks?\ ago$ ]]; then
echo "${BASH_REMATCH[1]}w ago"
return 0
fi
if [[ $value =~ ^([0-9]+)[[:space:]]+months?\ ago$ ]]; then
echo "${BASH_REMATCH[1]}m ago"
return 0
fi
if [[ $value =~ ^([0-9]+)[[:space:]]+month\(s\)\ ago$ ]]; then
echo "${BASH_REMATCH[1]}m ago"
return 0
fi
if [[ $value =~ ^([0-9]+)[[:space:]]+years?\ ago$ ]]; then
echo "${BASH_REMATCH[1]}y ago"
return 0
fi
echo "$value"
}
# Scan applications and collect information
scan_applications() {
# Cache configuration
@@ -195,7 +233,14 @@ scan_applications() {
# Second pass: process each app with parallel size calculation
local app_count=0
local total_apps=${#app_data_tuples[@]}
local max_parallel=10 # Process 10 apps in parallel
# Bound parallelism so small machines stay responsive
local max_parallel
max_parallel=$(get_optimal_parallel_jobs "io")
if [[ $max_parallel -lt 4 ]]; then
max_parallel=4
elif [[ $max_parallel -gt 16 ]]; then
max_parallel=16
fi
local pids=()
local inline_loading=false
if [[ "${MOLE_INLINE_LOADING:-}" == "1" || "${MOLE_INLINE_LOADING:-}" == "true" ]]; then
@@ -215,9 +260,9 @@ scan_applications() {
local app_size="N/A"
local app_size_kb="0"
if [[ -d "$app_path" ]]; then
# numeric size (KB) for sorting + human-readable for display
# Get size in KB, then format for display (single du call)
app_size_kb=$(du -sk "$app_path" 2> /dev/null | awk '{print $1}' || echo "0")
app_size=$(du -sh "$app_path" 2> /dev/null | cut -f1 || echo "N/A")
app_size=$(bytes_to_human "$((app_size_kb * 1024))")
fi
# Get real last used date from macOS metadata
@@ -633,26 +678,43 @@ main() {
rm -f "$apps_file"
return 0
fi
# Show selected apps, max 3 per line
# Show selected apps with clean alignment
echo -e "${BLUE}${ICON_CONFIRM}${NC} Selected ${selection_count} app(s):"
local idx=0
local line=""
local -a summary_rows=()
local max_name_width=0
local max_size_width=0
local name_trunc_limit=30
for selected_app in "${selected_apps[@]}"; do
IFS='|' read -r epoch app_path app_name bundle_id size last_used <<< "$selected_app"
local display_item="${app_name}(${size})"
if ((idx % 3 == 0)); then
# Start new line
[[ -n "$line" ]] && echo " $line"
line="$display_item"
else
# Add to current line
line="$line, $display_item"
local display_name="$app_name"
if [[ ${#display_name} -gt $name_trunc_limit ]]; then
display_name="${display_name:0:$((name_trunc_limit - 3))}..."
fi
((idx++))
[[ ${#display_name} -gt $max_name_width ]] && max_name_width=${#display_name}
local size_display="$size"
if [[ -z "$size_display" || "$size_display" == "0" || "$size_display" == "N/A" ]]; then
size_display="Unknown"
fi
[[ ${#size_display} -gt $max_size_width ]] && max_size_width=${#size_display}
local last_display
last_display=$(format_last_used_summary "$last_used")
summary_rows+=("$display_name|$size_display|$last_display")
done
((max_name_width < 16)) && max_name_width=16
((max_size_width < 5)) && max_size_width=5
local index=1
for row in "${summary_rows[@]}"; do
IFS='|' read -r name_cell size_cell last_cell <<< "$row"
printf " %2d. %-*s %*s | Last: %s\n" "$index" "$max_name_width" "$name_cell" "$max_size_width" "$size_cell" "$last_cell"
((index++))
done
# Print the last line
[[ -n "$line" ]] && echo " $line"
echo ""
# Execute batch uninstallation (handles confirmation)