Skip to content

Commit

Permalink
Use a single line cache file
Browse files Browse the repository at this point in the history
In c7c894a, a per-selection line-cache was introduced in order to
overcome some of the limitations of clipmenu at the time (for example,
missing duplicate detection). However, now we have all the features we
need to have a single line cache again, and having multiple line caches
has caused more trouble than it is worth.

For example, maintaining CM_MAX_CLIPS globally is extremely cumbersome,
so we don't do it, and CM_MAX_CLIPS is actually acted on per-selection.
We also have had bugs where we perform actions on cache files without
properly consulting other line caches, and while those can be fixed, the
simplest thing to do now is just to go back to having a single line
cache.
  • Loading branch information
cdown committed Mar 23, 2020
1 parent 773a140 commit f22fce7
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -3,7 +3,7 @@ language: bash
dist: xenial

script:
- shellcheck -s bash clipmenu clipmenud
- shellcheck -s bash clipmenu clipmenud clipdel clipfsck
- tests/test-clipmenu

matrix:
Expand Down
28 changes: 12 additions & 16 deletions clipdel
Expand Up @@ -7,12 +7,12 @@ if [[ $1 == -d ]]; then
shift
fi

major_version=5
major_version=6

shopt -s nullglob

cache_dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file_prefix=$cache_dir/line_cache
cache_file=$cache_dir/line_cache
lock_file=$cache_dir/lock
lock_timeout=2

Expand All @@ -35,10 +35,8 @@ EOF
exit 0
fi

line_cache_files=( "$cache_file_prefix"_* )

if (( ${#line_cache_files[@]} == 0 )); then
printf '%s\n' "No line cache files found, no clips exist" >&2
if ! [[ -f $cache_file ]]; then
printf '%s\n' "No line cache file found, no clips exist" >&2
exit 0 # Well, this is a kind of success...
fi

Expand All @@ -64,7 +62,7 @@ if (( CM_REAL_DELETE )) && [[ "$raw_pattern" == ".*" ]]; then
exit 0
else
mapfile -t matches < <(
sed -n "${sed_common_command}p" "${line_cache_files[@]}" |
sed -n "${sed_common_command}p" "$cache_file" |
sort -u
)

Expand All @@ -76,15 +74,13 @@ else
rm -f -- "$cache_dir/$ck"
done

for file in "${line_cache_files[@]}"; do
temp=$(mktemp)
# sed 'h' and 'g' here means save and restore the line, so
# timestamps are not removed from non-deleted lines. 'd' deletes the
# line and restarts, skipping 'g'/restore.
# https://www.gnu.org/software/sed/manual/html_node/Other-Commands.html#Other-Commands
sed "h;${sed_common_command}d;g" "$file" > "$temp"
mv -- "$temp" "$file"
done
temp=$(mktemp)
# sed 'h' and 'g' here means save and restore the line, so
# timestamps are not removed from non-deleted lines. 'd' deletes the
# line and restarts, skipping 'g'/restore.
# https://www.gnu.org/software/sed/manual/html_node/Other-Commands.html#Other-Commands
sed "h;${sed_common_command}d;g" "$cache_file" > "$temp"
mv -- "$temp" "$cache_file"

flock -u "$lock_fd"
else
Expand Down
12 changes: 6 additions & 6 deletions clipfsck
Expand Up @@ -2,12 +2,12 @@

: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"

major_version=5
major_version=6

shopt -s nullglob

cache_dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file_prefix=$cache_dir/line_cache
cache_file=$cache_dir/line_cache

declare -A cksums

Expand All @@ -16,11 +16,11 @@ while IFS= read -r line; do
cksums["$cksum"]="$line"

# Are all cache entries represented by a file?
cache_file=$cache_dir/$cksum
if ! [[ -f $cache_file ]]; then
printf 'cache entry without file: %s -> %s\n' "$line" "$cache_file" >&2
full_file=$cache_dir/$cksum
if ! [[ -f $full_file ]]; then
printf 'cache entry without file: %s -> %s\n' "$line" "$full_file" >&2
fi
done < <(cat "$cache_file_prefix"_* /dev/null | cut -d' ' -f2-)
done < <(cut -d' ' -f2- < "$cache_file")

# Are all files represented by a cache entry?
for file in "$cache_dir"/[012346789]*; do
Expand Down
8 changes: 4 additions & 4 deletions clipmenu
Expand Up @@ -4,12 +4,12 @@
: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"
: "${CM_HISTLENGTH=8}"

major_version=5
major_version=6

shopt -s nullglob

cache_dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file_prefix=$cache_dir/line_cache
cache_file=$cache_dir/line_cache

if [[ $1 == --help ]] || [[ $1 == -h ]]; then
cat << 'EOF'
Expand All @@ -33,7 +33,7 @@ if [[ "$CM_LAUNCHER" == rofi ]]; then
fi

list_clips() {
cat "$cache_file_prefix"_* /dev/null | LC_ALL=C sort -rnk 1 | cut -d' ' -f2- | awk '!seen[$0]++'
LC_ALL=C sort -rnk 1 < "$cache_file" | cut -d' ' -f2- | awk '!seen[$0]++'
}

if [[ "$CM_LAUNCHER" == rofi-script ]]; then
Expand All @@ -59,7 +59,7 @@ if ! [[ -f "$file" ]]; then
# We didn't find this in cache
printf 'FATAL: %s not in cache (%s missing)\n' "$chosen_line" "$file" >&2
printf 'Please report the following debug information:\n\n' >&2
wc -l "$cache_file_prefix"_* >&2
wc -l "$cache_file" >&2
grep -nFR "$chosen_line" "$cache_dir" >&2
stat "$file" >&2
exit 2
Expand Down
5 changes: 2 additions & 3 deletions clipmenud
Expand Up @@ -15,9 +15,9 @@ CM_MAX_CLIPS_THRESH=$(( CM_MAX_CLIPS + 100 ))
# shellcheck disable=SC2153
: "${CM_SELECTIONS=clipboard primary}"

major_version=5
major_version=6
cache_dir=$CM_DIR/clipmenu.$major_version.$USER/
cache_file_prefix=$cache_dir/line_cache
cache_file=$cache_dir/line_cache

# lock_file is the lock for *one* iteration of clipboard capture/propagation.
# session_lock_file is the lock to prevent multiple clipmenud daemons from
Expand Down Expand Up @@ -186,7 +186,6 @@ while true; do
fi

for selection in "${cm_selections[@]}"; do
cache_file=${cache_file_prefix}_$selection
data=$(_xsel -o --"$selection"; printf x)

debug "Data before stripping: $data"
Expand Down
4 changes: 2 additions & 2 deletions tests/test-clipmenu
Expand Up @@ -6,9 +6,9 @@ set -o pipefail

: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"

major_version=5
major_version=6
dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file=$dir/line_cache_primary
cache_file=$dir/line_cache

if [[ $0 == /* ]]; then
location=${0%/*}
Expand Down
4 changes: 2 additions & 2 deletions tests/test-perf
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

major_version=5
major_version=6

msg() {
printf '>>> %s\n' "$@" >&2
Expand All @@ -9,7 +9,7 @@ msg() {
: "${CM_DIR="${XDG_RUNTIME_DIR-"${TMPDIR-/tmp}"}"}"

dir=$CM_DIR/clipmenu.$major_version.$USER
cache_file=$dir/line_cache_primary
cache_file=$dir/line_cache

log=$(mktemp)
tim=$(mktemp)
Expand Down

0 comments on commit f22fce7

Please sign in to comment.