本文目录导读:

我来详细介绍Shell脚本实现LRU(Least Recently Used)缓存的方法。
基础实现 - 使用文件系统
简单文件版本
#!/bin/bash
# LRU缓存文件路径
CACHE_FILE="/tmp/lru_cache.txt"
CACHE_MAX_SIZE=5
# 初始化缓存文件
init_cache() {
if [ ! -f "$CACHE_FILE" ]; then
touch "$CACHE_FILE"
fi
}
# 获取缓存
cache_get() {
local key="$1"
local value
# 查找key是否存在
value=$(grep "^$key:" "$CACHE_FILE" 2>/dev/null | cut -d: -f2)
if [ -n "$value" ]; then
# 更新访问时间 - 将该项移到文件末尾
grep -v "^$key:" "$CACHE_FILE" > "${CACHE_FILE}.tmp"
echo "$key:$value" >> "${CACHE_FILE}.tmp"
mv "${CACHE_FILE}.tmp" "$CACHE_FILE"
echo "$value"
fi
}
# 设置缓存
cache_set() {
local key="$1"
local value="$2"
# 如果key已存在,先删除旧记录
if grep -q "^$key:" "$CACHE_FILE" 2>/dev/null; then
grep -v "^$key:" "$CACHE_FILE" > "${CACHE_FILE}.tmp"
mv "${CACHE_FILE}.tmp" "$CACHE_FILE"
fi
# 添加新记录
echo "$key:$value" >> "$CACHE_FILE"
# 检查并清理超出大小的项目
local lines=$(wc -l < "$CACHE_FILE")
if [ "$lines" -gt "$CACHE_MAX_SIZE" ]; then
# 删除最旧的项目(文件头部)
tail -n "$CACHE_MAX_SIZE" "$CACHE_FILE" > "${CACHE_FILE}.tmp"
mv "${CACHE_FILE}.tmp" "$CACHE_FILE"
fi
}
# 删除缓存项
cache_del() {
local key="$1"
grep -v "^$key:" "$CACHE_FILE" > "${CACHE_FILE}.tmp"
mv "${CACHE_FILE}.tmp" "$CACHE_FILE"
}
# 清空缓存
cache_clear() {
> "$CACHE_FILE"
}
# 查看缓存状态
cache_status() {
echo "=== LRU Cache Status ==="
echo "Max Size: $CACHE_MAX_SIZE"
echo "Current Size: $(wc -l < "$CACHE_FILE")"
echo "Contents (least recent first):"
cat "$CACHE_FILE" | while IFS=: read -r key value; do
echo " $key -> $value"
done
}
使用关联数组的内存版本
#!/bin/bash
# 内存LRU缓存实现(使用关联数组)
declare -A LRU_CACHE
declare -a LRU_ORDER=()
CACHE_MAX_SIZE=10
# 获取缓存值
lru_get() {
local key="$1"
if [[ -v LRU_CACHE["$key"] ]]; then
# 更新访问顺序
update_access_order "$key"
echo "${LRU_CACHE[$key]}"
return 0
fi
return 1
}
# 设置缓存值
lru_set() {
local key="$1"
local value="$2"
# 如果key已存在,更新值
if [[ -v LRU_CACHE["$key"] ]]; then
LRU_CACHE["$key"]="$value"
update_access_order "$key"
else
# 检查缓存是否已满
if [ ${#LRU_ORDER[@]} -ge "$CACHE_MAX_SIZE" ]; then
# 移除最久未使用的项
local oldest="${LRU_ORDER[0]}"
unset LRU_CACHE["$oldest"]
LRU_ORDER=("${LRU_ORDER[@]:1}")
fi
# 添加新项
LRU_CACHE["$key"]="$value"
LRU_ORDER+=("$key")
fi
}
# 更新访问顺序
update_access_order() {
local key="$1"
local index=-1
for i in "${!LRU_ORDER[@]}"; do
if [ "${LRU_ORDER[$i]}" == "$key" ]; then
index=$i
break
fi
done
if [ $index -ge 0 ]; then
# 移除当前位置
unset 'LRU_ORDER[$index]'
# 重新索引数组
LRU_ORDER=("${LRU_ORDER[@]}")
# 添加到末尾
LRU_ORDER+=("$key")
fi
}
# 删除缓存项
lru_del() {
local key="$1"
if [[ -v LRU_CACHE["$key"] ]]; then
unset LRU_CACHE["$key"]
# 从顺序数组中移除
for i in "${!LRU_ORDER[@]}"; do
if [ "${LRU_ORDER[$i]}" == "$key" ]; then
unset 'LRU_ORDER[$i]'
LRU_ORDER=("${LRU_ORDER[@]}")
break
fi
done
fi
}
# 显示缓存状态
lru_status() {
echo "=== Memory LRU Cache ==="
echo "Max Size: $CACHE_MAX_SIZE"
echo "Current Size: ${#LRU_CACHE[@]}"
echo "Access Order (oldest first):"
for key in "${LRU_ORDER[@]}"; do
echo " $key -> ${LRU_CACHE[$key]}"
done
}
使用临时文件的增强版本
#!/bin/bash
# LRU缓存类
LRUCache() {
# 构造函数
local -n self=$1
self[base_dir]="/tmp/lru_cache_$$"
self[max_size]=10
# 初始化
mkdir -p "${self[base_dir]}"
# 获取缓存
get() {
local key="$1"
local cache_file="${self[base_dir]}/${key}"
if [ -f "$cache_file" ]; then
# 更新时间戳
touch "$cache_file"
cat "$cache_file"
return 0
fi
return 1
}
# 设置缓存
set() {
local key="$1"
local value="$2"
local cache_file="${self[base_dir]}/${key}"
echo "$value" > "$cache_file"
# 检查并淘汰
evict_if_needed
}
# 淘汰最久未使用的
evict_if_needed() {
local count=$(ls -1t "${self[base_dir]}/" 2>/dev/null | wc -l)
if [ "$count" -gt "${self[max_size]}" ]; then
# 找到最久未访问的文件并删除
ls -1t "${self[base_dir]}/" | tail -n $((count - self[max_size])) |
while read file; do
rm -f "${self[base_dir]}/$file"
done
fi
}
# 获取统计信息
stats() {
echo "Cache directory: ${self[base_dir]}"
echo "Max size: ${self[max_size]}"
echo "Current size: $(ls -1 "${self[base_dir]}/" 2>/dev/null | wc -l)"
echo "Recent access order (most recent first):"
ls -1t "${self[base_dir]}/" 2>/dev/null | head -10
}
# 清理
cleanup() {
rm -rf "${self[base_dir]}"
}
}
# 使用示例
example_usage() {
# 创建缓存实例
declare -A my_cache
LRUCache my_cache
my_cache[max_size]=5
# 设置缓存
my_cache set "key1" "value1"
my_cache set "key2" "value2"
my_cache set "key3" "value3"
# 获取缓存
echo "key1 value: $(my_cache get 'key1')"
# 显示状态
my_cache stats
# 清理
my_cache cleanup
}
使用SQLite的持久化版本
#!/bin/bash
# SQLite LRU缓存实现
LRU_DB="/tmp/lru_cache.db"
# 初始化数据库
init_sqlite_cache() {
sqlite3 "$LRU_DB" "CREATE TABLE IF NOT EXISTS cache (
key TEXT PRIMARY KEY,
value TEXT,
access_time INTEGER
);"
}
# 获取缓存
sqlite_cache_get() {
local key="$1"
init_sqlite_cache
local result=$(sqlite3 "$LRU_DB" "SELECT value, access_time FROM cache WHERE key='$key'")
if [ -n "$result" ]; then
# 更新时间戳
sqlite3 "$LRU_DB" "UPDATE cache SET access_time=$(date +%s) WHERE key='$key'"
echo "$result" | cut -d'|' -f1
return 0
fi
return 1
}
# 设置缓存
sqlite_cache_set() {
local key="$1"
local value="$2"
local max_size=10
init_sqlite_cache
# 插入或更新
sqlite3 "$LRU_DB" "INSERT OR REPLACE INTO cache (key, value, access_time)
VALUES ('$key', '$value', $(date +%s))"
# 检查并淘汰
local count=$(sqlite3 "$LRU_DB" "SELECT COUNT(*) FROM cache")
if [ "$count" -gt "$max_size" ]; then
# 删除最久未使用的记录
sqlite3 "$LRU_DB" "DELETE FROM cache WHERE key IN (
SELECT key FROM cache ORDER BY access_time ASC LIMIT $((count - max_size))
)"
fi
}
完整测试脚本
#!/bin/bash
# 包含LRU实现
source ./lru_cache.sh
# 测试函数
test_lru_cache() {
echo "=== Testing LRU Cache ==="
# 使用内存版本
echo "Testing memory cache..."
lru_set "key1" "value1"
lru_set "key2" "value2"
lru_set "key3" "value3"
echo "Get key1: $(lru_get 'key1')"
echo "Get key2: $(lru_get 'key2')"
lru_status
# 测试淘汰
echo -e "\nAdding more items to trigger eviction..."
lru_set "key4" "value4"
lru_set "key5" "value5"
lru_set "key6" "value6"
lru_status
echo "Try to get evicted key (key3): $(lru_get 'key3' || echo 'NOT FOUND')"
}
# 执行测试
test_lru_cache
最佳实践建议
-
选择合适的实现方式:
- 小型缓存:使用关联数组
- 持久化需求:使用文件或SQLite
- 高性能需求:使用临时文件
-
并发安全:
- 使用文件锁处理并发访问
- 考虑使用
flock命令
-
性能优化:
- 使用哈希函数分散文件存储
- 实现二级缓存策略
- 定期清理过期项
-
错误处理:
- 检查文件操作是否成功
- 处理并发写入冲突
- 实现优雅的清理机制
这些实现可以根据你的具体需求进行调整和优化,选择哪种方式取决于你的使用场景、性能要求和数据持久化需求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播