summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2014-08-16 23:05:40 -0400
committerDave Reisner <dreisner@archlinux.org>2014-08-16 23:05:40 -0400
commit784a38709849f25b71cab585c73c6ba509de38ad (patch)
tree626dea04695a1991f633a1722595c772b473a94c
parentf40e18e6d1e442aecb41be365832a86aa9acab5d (diff)
downloadasp32-784a38709849f25b71cab585c73c6ba509de38ad.tar.xz
remotes: move refcaching to disk
This speeds up a lot of operations substantially, at the cost of occasionally being wrong for a little while when new packages are added/removed from the repositories. Mostly, this is for the sake of the completions.
-rw-r--r--asp.in3
-rw-r--r--man/asp.1.txt4
-rw-r--r--remote.inc.sh33
3 files changed, 35 insertions, 5 deletions
diff --git a/asp.in b/asp.in
index 94cc420..cb983a4 100644
--- a/asp.in
+++ b/asp.in
@@ -5,6 +5,7 @@ ARCH_GIT_REPOS=(packages community)
OPT_ARCH=$(uname -m)
OPT_FORCE=0
: ${ASPROOT:=$HOME/asp}
+: ${ASPCACHE:=$ASPROOT/cache}
m4_include(util.inc.sh)
m4_include(remote.inc.sh)
@@ -88,6 +89,8 @@ initialize() {
migrate_bare_repo
fi
+ [[ -d $ASPCACHE ]] || mkdir -p "$ASPCACHE"
+
[[ -f .asp ]] && return 0
git init || return 1
diff --git a/man/asp.1.txt b/man/asp.1.txt
index ef978bf..6bd2a76 100644
--- a/man/asp.1.txt
+++ b/man/asp.1.txt
@@ -100,6 +100,10 @@ Environment
Determines where the metadata is stored for locally tracked packages. Defaults
to '$HOME/asp'.
+*ASPCACHE*::
+ Determines where cached data is stored. Defaults to '$ASPROOT/cache'. Data in
+ this directory can always be safely deleted.
+
Authors
-------
Dave Reisner <d@falconindy.com>
diff --git a/remote.inc.sh b/remote.inc.sh
index a615d24..2cce6ba 100644
--- a/remote.inc.sh
+++ b/remote.inc.sh
@@ -1,14 +1,37 @@
declare -A refcache=()
+__remote_refcache_get() {
+ local remote=$1 ttl=3600 now= cachetime= cachefile=$ASPCACHE/remote-$remote
+
+ # miss
+ cachetime=$(stat -c %Y "$cachefile" 2>/dev/null) || return 1
+
+ printf -v now '%(%s)T' -1
+
+ # miss
+ (( now > (cachetime + ttl) )) && return 1
+
+ # hit
+ mapfile -t "$2" <"$cachefile"
+}
+
+__remote_refcache_update() {
+ local remote=$1 cachefile=$ASPCACHE/remote-$remote
+
+ trap "rm -f '$cachefile~'" RETURN
+
+ git ls-remote "$remote" 'refs/heads/packages/*' |
+ awk '{ sub(/refs\/heads\//, "", $2); print $2 }' >"$cachefile~" &&
+ mv "$cachefile"{~,}
+}
+
remote_get_all_refs() {
local remote=$1
- if [[ -z ${refcache["$remote"]+cached} ]]; then
- refcache["$remote"]=$(git ls-remote "$remote" 'refs/heads/packages/*' |
- awk '{ sub(/refs\/heads\//, "", $2); print $2 }')
+ if ! __remote_refcache_get "$remote" "$2"; then
+ __remote_refcache_update "$remote"
+ __remote_refcache_get "$remote" "$2"
fi
-
- mapfile -t "$2" <<<"${refcache["$remote"]}"
}
remote_has_package() {