# HG changeset patch # User Aleksej Bobylev # Date 1447351980 -7200 # Node ID d62dc010e0eeb34147eb1197e10caf8815076002 # Parent 64537d742a0036daa96a48432f190eab6d7f489a remove: speed up to a hundred times diff -r 64537d742a00 -r d62dc010e0ee modules/recharge --- a/modules/recharge Mon Nov 09 13:26:53 2015 +0200 +++ b/modules/recharge Thu Nov 12 20:13:00 2015 +0200 @@ -27,10 +27,14 @@ # Download a file from specified mirror get_from_mirror() { + debug "get_from_mirror($1)" + debug " mirror='$mirror'" case "$mirror" in http://* | https://* | ftp://*) + debug " wget -c -q -T 30 -U '$UA' '$mirror$1'" wget -c -q -T 30 -U "$UA" "$mirror$1" 2>/dev/null;; *) + debug " ln -sf '$mirror$1' ." ln -sf "$mirror$1" .;; esac status diff -r 64537d742a00 -r d62dc010e0ee modules/remove --- a/modules/remove Mon Nov 09 13:26:53 2015 +0200 +++ b/modules/remove Thu Nov 12 20:13:00 2015 +0200 @@ -13,25 +13,6 @@ -remove_with_path() { - # Avoid dirname errors by checking for argument. - [ -n "$1" ] || return - - local dir - rm -f $1 2>/dev/null - dir="$1" - while [ "$dir" != "/" ]; do - dir="$(dirname "$dir")" - rmdir "$dir" 2>/dev/null || break - done -} - - -grepesc() { - sed 's/\[/\\[/g' -} - - # Log activity log_pkg() { @@ -126,22 +107,74 @@ # [2/4] Removing files action 'Removing all files installed...' + +# NOTE: package 'faenza-icon-theme' install time: 12s; removing time ~ 11min on my system o_O +# After optimization: 6s! (Long) for-loops are (big) evil ;) + +# NOTE: many packages contains filenames with spaces: +# lzcat /var/lib/tazpkg/files.list.lzma | awk -F" " '{if(NF>2)print $1}' | sed 's|:$||' | uniq +# Redefine IFS to only-new-line field separator: +IFS=$'\n' + +files2remove="$(mktemp)" +dirs2remove="$(mktemp)" + +debug '\nDetermine which files to remove...' if [ -f "$INSTALLED/$PACKAGE/modifiers" ]; then - for file in $(cat "$INSTALLED/$PACKAGE/files.list"); do - for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do - [ -f "$INSTALLED/$mod/files.list" ] && \ - [ $(grep "^$(echo $file | grepesc)$" "$INSTALLED/$mod/files.list" | wc -l) -gt 1 ] && \ - continue 2 - done - debug "remove_with_path ($root$file)" - remove_with_path "$root$file" + debug ' (modifiers detected)' + + mods="$(mktemp)" + for mod in $(cat "$INSTALLED/$PACKAGE/modifiers"); do + cat "$INSTALLED/$mod/files.list" >> "$mods" 2>/dev/null done + + awk -vroot="$root" -vfl="$INSTALLED/$PACKAGE/files.list" ' + { + if (FILENAME == fl) + f[$0] = 1; + else + f[$0] = ""; + } + END { + for (i in f) { + if (f[i] == 1) printf "%s%s\n", root, i; + } + }' "$INSTALLED/$PACKAGE/files.list" "$mods" > "$files2remove" + rm "$mods" else - for file in $(cat "$INSTALLED/$PACKAGE/files.list"); do - debug "remove_with_path ($root$file)" - remove_with_path "$root$file" + debug ' (modifiers not detected)' + + awk -vroot="$root" '{ printf "%s%s\n", root, $0; }' \ + "$INSTALLED/$PACKAGE/files.list" > "$files2remove" +fi + +debug 'Removing files...' +xargs rm -f < "$files2remove" + +debug 'Determine which folders to remove...' +awk ' +BEGIN { + FS = "/"; OFS = "/"; +} +{ + # removing filename beyond the last "/" + $NF = ""; + if (! a[$0]) { + a[$0] = 1; print; + } +}' "$files2remove" | sed 's|/$||' > "$dirs2remove" + +debug 'Removing folders...' +for dir2r in $(cat "$dirs2remove"); do + dir="$dir2r" + while [ -n "$dir" ]; do + rmdir "$dir" 2>/dev/null || break + dir="${dir%/*}" done -fi +done +rm "$files2remove" "$dirs2remove" +unset IFS + status # [3/4] Post-remove commands