From 784a38709849f25b71cab585c73c6ba509de38ad Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sat, 16 Aug 2014 23:05:40 -0400 Subject: 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. --- asp.in | 3 +++ man/asp.1.txt | 4 ++++ remote.inc.sh | 33 ++++++++++++++++++++++++++++----- 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 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() { -- cgit v1.2.3-70-g09d2