commit 6edf3c437bb9bafb41e0e7383ff4def6a794cd13
parent f0fe96955af9bb0bacea06b93752fe51c72d3024
Author: Chris Down <chris@chrisdown.name>
Date: Fri, 6 Jan 2017 14:02:47 +0000
perf: Add naive but performant path
Diffstat:
M | clipmenu | | | 35 | +++++++++++++++++++++++++---------- |
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/clipmenu b/clipmenu
@@ -3,17 +3,10 @@
shopt -s nullglob
# We use this to make sure the cache files are sorted bytewise
-LC_COLLATE=C
-
-declare -A selections
+export LC_COLLATE=C
cache_file=/tmp/clipmenu.$USER/line_cache
-# We use tac since we want newest to oldest, and we append in clipmenud
-while IFS='|' read -r full_file first_line; do
- selections[$first_line]=$full_file
-done < <(tac "$cache_file")
-
# It's okay to hardcode `-l 8` here as a sensible default without checking
# whether `-l` is also in "$@", because the way that dmenu works allows a later
# argument to override an earlier one. That is, if the user passes in `-l`, our
@@ -22,10 +15,32 @@ chosen_line=$(sed 's/^[^|]\+|//' "$cache_file" | tac | uniq | dmenu -l 8 "$@")
[[ $chosen_line ]] || exit 1
+# Naive, but performant path, only follow expensive path if it doesn't work
+out_line=$(grep -F "|$chosen_line" "$cache_file")
+out_length=$(wc -l <<< "$out_line")
+
+if (( out_length == 1 )); then
+ # Cheap path succeded
+ file=${out_line%%|*}
+elif (( out_length > 1 )); then
+ # Cheap path failed
+ while IFS='|' read -r full_file first_line; do
+ if [[ $first_line == "$chosen_line" ]]; then
+ file=$full_file
+ break
+ fi
+ done <<< "$out_line"
+else
+ # We didn't find this in cache
+ printf 'FATAL: %s not in cache, run clipmenu-fsck\n' "$chosen_line" >&2
+ exit 2
+fi
+
+
for selection in clipboard primary; do
if type -p xsel >/dev/null 2>&1; then
- xsel -i --"$selection" < "${selections[$chosen_line]}"
+ xsel -i --"$selection" < "$file"
else
- xclip -sel "$selection" < "${selections[$chosen_line]}"
+ xclip -sel "$selection" < "$file"
fi
done