From f2cafe056720b7e83220ee1bb9a2f427a2411d24 Mon Sep 17 00:00:00 2001 From: shenmo <jifengshenmo@outlook.com> Date: Fri, 28 Mar 2025 17:29:29 +0000 Subject: [PATCH] Sync:https://gitee.com/GXDE-OS/aptss/commit/674f871cec7aaf76e948b004f3334e414150fb3f Signed-off-by: shenmo <jifengshenmo@outlook.com> --- tool/apt-fast/ss-apt-fast | 75 ++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/tool/apt-fast/ss-apt-fast b/tool/apt-fast/ss-apt-fast index d7b7b0e..17abb7b 100755 --- a/tool/apt-fast/ss-apt-fast +++ b/tool/apt-fast/ss-apt-fast @@ -430,52 +430,40 @@ get_uris(){ CLEANUP_STATE="$?" if [ "$CLEANUP_STATE" -ne 0 ] then - msg "Package manager quit with exit code.Here is the log" "warning" + msg "Package manager quit with exit code. Here is the log" "warning" msg "包管理器以错误代码退出.日志如下" "warning" msg "${uris_full}" exit "$CLEANUP_STATE" fi prepare_auth - local tmpdir=$(mktemp -d) || { + local tmpdir + tmpdir=$(mktemp -d) || { msg "Failed to create tmp dir" "warning" msg "无法创建临时目录" "warning" exit 1 } ## --print-uris format is: # 'fileurl' filename filesize checksum_hint:filechecksum + # 修改:process_package函数增加第二个参数表示当前线程的临时输出文件 process_package() { - local pkg_uri_info="$@" - - local display_line="" # 添加局部变量并初始化为空 - + local pkg_uri_info="$1" + local thread_file="$2" + local display_line="" # 初始化显示信息为空 IFS=' ' read -r uri filename filesize checksum_string _ <<<"$pkg_uri_info" - [ -z "$uri" ] && continue + [ -z "$uri" ] && return uri="${uri//"'"/}" [ "$APT_FAST_APT_AUTH" -ne 0 ] && uri="$(get_auth "$uri")" IFS=':' read -r hash_algo checksum _ <<<"$checksum_string" if [[ "$filename" == *%* ]]; then # decode url string - # translates %xx but must not convert '+' in spaces filename_decoded="$(printf '%b' "${filename//%/\\x}")" else - # most filenames do not contain %, so skip decoding them to improve the performance. - # the overhead of decoding is >1ms due to the use of subshell and printf, while the one of assignment is ~1us. filename_decoded="$filename" fi IFS='_' read -r pkg_name_decoded pkg_version_decoded _ <<<"$filename_decoded" - - display_line+="$pkg_name_decoded $pkg_version_decoded $filesize\n" - - ## whole uri comes encoded (urlencoded). Filename must NOT be decoded because - # plain aptitude do not decode it when download and install it. Therefore, we - # will have ugly named packages at /var/cache/apt/archives but is the standard - # behavior. - # But package version must be decoded, otherways package=version calls will - # not work. - if [ -n "$HASH_SUPPORTED" ]; then case "$hash_algo" in SHA512) [ -z "$SHA512_SUPPORTED" ] && hash_algo= || hash_algo=sha-512 ;; @@ -530,30 +518,27 @@ get_uris(){ hash_algo= fi + # 原来利用文件锁写入,现在改为写入当前线程的临时文件 + { + get_mirrors "$uri" + [ -n "$hash_algo" ] && echo " checksum=$hash_algo=$checksum" + echo " out=$filename" + } >> "$thread_file" - # 使用文件锁安全写入下载列表 - ( - flock -x 200 # 获取排他锁 - { - get_mirrors "$uri" - [ -n "$hash_algo" ] && echo " checksum=$hash_algo=$checksum" - echo " out=$filename" - } >> "$DLLIST" - ) 200>>"$DLLIST" # 使用文件描述符200关联锁文件 - - # 将显示信息和文件大小存入临时文件 - echo "$display_line" >> "$tmpdir/display" + echo -e "$display_line" >> "$tmpdir/display" echo "$filesize" >> "$tmpdir/sizes" } - # 主并行处理逻辑(新增线程控制) + # 主并行处理逻辑 mapfile -t pkg_uri_list < <(echo "$uris_full" | grep -E "^'(http(s|)|(s|)ftp)://") total_pkgs=${#pkg_uri_list[@]} threads=${THREADS:-4} # 默认4线程 per_thread=$(( (total_pkgs + threads - 1) / threads )) # 向上取整 - # 分割任务到不同线程 + # 分配任务到不同线程,每个线程使用自己的临时文件 for ((i=0; i<threads; i++)); do + thread_file="${DLLIST}.thread.${i}" + > "$thread_file" # 清空或创建临时文件 start=$((i * per_thread)) end=$((start + per_thread -1)) [ $end -ge $total_pkgs ] && end=$((total_pkgs -1)) @@ -562,7 +547,7 @@ get_uris(){ ( for ((j=start; j<=end; j++)); do [ -z "${pkg_uri_list[j]}" ] && continue - process_package "${pkg_uri_list[j]}" + process_package "${pkg_uri_list[j]}" "$thread_file" done ) & done @@ -570,6 +555,15 @@ get_uris(){ # 等待所有后台任务完成 wait + # 合并所有线程的临时文件到最终的 $DLLIST 中(保留之前添加的 header) + for ((i=0; i<threads; i++)); do + thread_file="${DLLIST}.thread.${i}" + if [ -f "$thread_file" ]; then + cat "$thread_file" >> "$DLLIST" + rm -f "$thread_file" + fi + done + # 合并显示信息 if [ -f "$tmpdir/display" ]; then DOWNLOAD_DISPLAY+="\n$(cat "$tmpdir/display")" @@ -582,12 +576,10 @@ get_uris(){ # 清理临时目录 rm -rf "$tmpdir" - - #cat "$DLLIST" - #exit } + display_downloadfile(){ if [ -n "$VERBOSE_OUTPUT" ]; then cat "$DLLIST" @@ -598,10 +590,10 @@ display_downloadfile(){ while IFS=' ' read -r pkg ver size _; do [ -z "$pkg" ] && continue printf '%s%-40s %-20s %10s\n' "$aptfast_prefix" "$pkg" "$ver" "$size" - done <<<"$(echo -e "$DOWNLOAD_DISPLAY" | sort "${DISPLAY_SORT_OPTIONS[@]}" | numfmt "${DISPLAY_NUMFMT_OPTIONS[@]}" --field=3)" + done <<<"$(echo -e "$DOWNLOAD_DISPLAY" | sort "${DISPLAY_SORT_OPTIONS[@]}" | numfmt --to=iec-i --suffix=B --field=3)" fi - msg "Download size: $(echo "$DOWNLOAD_SIZE" | numfmt "${DISPLAY_NUMFMT_OPTIONS[@]}")" "normal" - msg "下载大小: $(echo "$DOWNLOAD_SIZE" | numfmt "${DISPLAY_NUMFMT_OPTIONS[@]}")" "normal" + msg "Download size: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal" + msg "下载大小: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal" } @@ -835,3 +827,4 @@ else fi # After error or all done remove our lockfile (done with EXIT trap) +