summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2014-02-15 18:43:48 +0100
committerJean Delvare <jdelvare@suse.de>2014-02-15 18:43:48 +0100
commitaadae7a30499c318ae18cb6b216f1d7fe60e49b7 (patch)
tree11c0db13988f16561fe6ef1e298e3985f5cd769b
parent1b95644e3a00f07a6711c881d2dcdac14206a57e (diff)
downloadquilt-aadae7a30499c318ae18cb6b216f1d7fe60e49b7.tar.gz
patches: Optimize the multiple files case
I didn't put too many thoughts when adding support for multiple files to the "patches" command. The nested loop approach turns out to be very inefficient for unapplied patches. Get rid of the innermost loop by building a single pattern matching all filenames at once. That way, performance no longer depends on the number of files (as far as unapplied patches are concerned.)
-rw-r--r--quilt/patches.in22
-rw-r--r--quilt/scripts/patchfns.in14
2 files changed, 23 insertions, 13 deletions
diff --git a/quilt/patches.in b/quilt/patches.in
index 6ec5e01..89c5b86 100644
--- a/quilt/patches.in
+++ b/quilt/patches.in
@@ -88,7 +88,7 @@ scan_unapplied()
{
local color=$1 prefix=$2 strip
shift 2
- local patch file match
+ local patch file
local -a files_bre
# Quote each file name only once
@@ -97,23 +97,19 @@ scan_unapplied()
files_bre[${#files_bre[@]}]=$(quote_bre "$file")
done
+ # "Or" all files in a single pattern
+ file=\\\($(array_join \\\| "${files_bre[@]}")\\\)
+
for patch in "$@"
do
strip=$(patch_strip_level $patch)
[ "$strip" = ab ] && strip=1
- match=
- for file in "${files_bre[@]}"
- do
- if touched_by_patch $strip $patch \
- | grep -q "^$file\$"
- then
- match=1
- break
- fi
- done
-
- [ -z "$match" ] || echo "$color$prefix$(print_patch $patch)$color_clear"
+ if touched_by_patch $strip "$patch" \
+ | grep -q "^$file\$"
+ then
+ echo "$color$prefix$(print_patch $patch)$color_clear"
+ fi
done
}
diff --git a/quilt/scripts/patchfns.in b/quilt/scripts/patchfns.in
index 42e8de8..e00c819 100644
--- a/quilt/scripts/patchfns.in
+++ b/quilt/scripts/patchfns.in
@@ -76,6 +76,20 @@ trap run_exit_handlers EXIT
# ========================================================
+# Join multiple stings using the given separator.
+array_join()
+{
+ local sep=$1 str=$2
+ shift 2
+
+ printf %s "$str"
+
+ for str in "$@"
+ do
+ printf %s%s "$sep" "$str"
+ done
+}
+
# Quote a string for use in a basic regular expression.
quote_bre()
{