LRU 和 DiskLRU實現相冊緩存器

我是寫Linux后端的(golang、c++、py),后端緩存算法通常是指的是內存里面的lru、或diskqueue,都是獨立使用。 很少有用內存lru與disklru結合的場景需求。近段時間研究android開發,里面有一些設計思想值得后端學習。

寫這篇文章的原因:
看到了android開發里面的一個片段
在這里插入圖片描述

于是在畫板里面手繪下圖:
在這里插入圖片描述

為了簡化測試,用Python編程語言實現

import tkinter as tk
from tkinter import ttk, messagebox
from PIL import Image, ImageTk, ImageOps
import requests
from io import BytesIO
import threading
import queue
from functools import lru_cache
from diskcache import Cache
import os# 配置緩存
CACHE_DIR = "image_cache"
os.makedirs(CACHE_DIR, exist_ok=True)
disk_cache = Cache(CACHE_DIR)  # 磁盤緩存(自動管理容量)@lru_cache(maxsize=5)  # LRU緩存(僅記錄URL)
def get_from_lru(url):passclass ImageLoader:def __init__(self):self.queue = queue.Queue()self.thread = threading.Thread(target=self._worker, daemon=True)self.thread.start()def load(self, url, callback):self.queue.put((url, callback))def _worker(self):while True:url, callback = self.queue.get()data = Nonecache_type = "error"# 檢查LRUif get_from_lru.cache_info().currsize > 0:data = disk_cache.get(url)if data:cache_type = "lru"# 檢查磁盤if not data:data = disk_cache.get(url)if data:cache_type = "disk"get_from_lru(url)  # 更新LRU標記# 網絡加載if not data:try:res = requests.get(url, timeout=10)res.raise_for_status()data = res.contentcache_type = "network"disk_cache.set(url, data)  # 自動處理容量限制get_from_lru(url)except Exception as e:callback(None, cache_type)continue# 返回結果try:img = Image.open(BytesIO(data))callback(img, cache_type)except:callback(None, "error")class ImageViewerApp:def __init__(self, root):self.root = rootself.root.title("圖片查看器")self.urls = [f"https://picsum.photos/seed/img{i}/800/600" for i in range(1, 11)]self.current = 0self.loader = ImageLoader()self._create_widgets()def _create_widgets(self):frame = ttk.Frame(self.root, padding=10)frame.pack(fill=tk.BOTH, expand=True)# 圖片顯示區域self.img_label = ttk.Label(frame)self.img_label.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# 導航按鈕btn_frame = ttk.Frame(frame)btn_frame.pack(fill=tk.X, pady=5)self.prev_btn = ttk.Button(btn_frame, text="? 上一張", command=self.prev_image)self.prev_btn.pack(side=tk.LEFT, padx=5)self.next_btn = ttk.Button(btn_frame, text="下一張 ?", command=self.next_image)self.next_btn.pack(side=tk.RIGHT, padx=5)# 緩存狀態self.status_label = ttk.Label(frame, text="緩存狀態: LRU(0/5), 磁盤(0/8)")self.status_label.pack(fill=tk.X, pady=2)# 加載指示器self.loading = ttk.Label(self.img_label, text="加載中...", font=("SimHei", 12))def _load_image(self, index):self.current = indexurl = self.urls[index]self.status_label.config(text="加載中...")self.loading.place(relx=0.5, rely=0.5, anchor="center")self.prev_btn.config(state=tk.DISABLED)self.next_btn.config(state=tk.DISABLED)self.loader.load(url, self._on_loaded)def _on_loaded(self, img, cache_type):self.root.after(0, lambda: self._update_display(img, cache_type))def _update_display(self, img, cache_type):self.loading.place_forget()self.prev_btn.config(state=tk.NORMAL)self.next_btn.config(state=tk.NORMAL)if img:# 調整圖片大小max_w = self.img_label.winfo_width() - 20max_h = self.img_label.winfo_height() - 20img = ImageOps.contain(img, (max_w or 500, max_h or 400))self.photo = ImageTk.PhotoImage(img)self.img_label.config(image=self.photo)# 更新緩存狀態lru = get_from_lru.cache_info().currsizedisk = len(disk_cache)self.status_label.config(text=f"緩存狀態: LRU({lru}/5) [{cache_type.upper()}], 磁盤({disk}/8)")else:messagebox.showerror("錯誤", "無法加載圖片")def prev_image(self):self._load_image((self.current - 1) % 10)def next_image(self):self._load_image((self.current + 1) % 10)if __name__ == "__main__":root = tk.Tk()root.geometry("800x600")app = ImageViewerApp(root)app._load_image(0)root.mainloop()

測試效果:
經過緩存的圖片從內存或文件加載,速度快了很多。 用空間換時間_
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84181.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84181.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84181.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

可視化預警:如何讓生產風險預警更高效?

你有沒有遇到過這種情況? 明明設備已經開始發熱報警,但操作人員還在繼續運行; 或者某個參數已經接近危險值,卻沒人注意到; 甚至問題早就埋下了隱患,只是當時沒發現…… 這些情況的背后,其實都…

【MPC-C++】qpOASES 源碼編譯與鏈接,編譯器設置細節

qpOASES 源碼編譯與鏈接 克隆源碼 git clone https://github.com/coin-or/qpOASES.gitcd qpOASES mkdir build cd build接下來是構建,有一些細節。 查看 CMakeLists.txt,發現如果不顯示指定 CMAKE_BUILD_TYPE 構建版本,會自動編譯 Release…

【11408學習記錄】考研數學攻堅:行列式本質、性質與計算全突破

行列式 數學線性代數一、對象(元素):向量二、運算三、行列式3.1 第一種定義——行列式的本質定義3.2 行列式的性質性質1:行列互換,其值不變性質2:若行列式中某行(列)元素全為零&…

Qt/C++開發監控GB28181系統/取流協議/同時支持udp/tcp被動/tcp主動

一、前言說明 在2011版本的gb28181協議中,拉取視頻流只要求udp方式,從2016開始要求新增支持tcp被動和tcp主動兩種方式,udp理論上會丟包的,所以實際使用過程可能會出現畫面花屏的情況,而tcp肯定不丟包,起碼…

小木的算法日記-線段樹

🌳 線段樹 (Segment Tree):玩轉區間作的終極利器 你好,未來的算法大師! 想象一下,你正在處理一個巨大的數據集,比如某個電商網站一整天的用戶點擊流。老板突然問你:“下…

Day24 元組和OS模塊

1、元組(有序 不可變 可重復) 管道工程中pipeline類接收的是一個包含多個小元組的列表作為輸入。可以這樣理解這個結構: (1) 列表 []: 定義了步驟執行的先后順序。Pipeline 會按照列表中的順序依次處理數據。之所以用列…

Auto-Coder使用GPT-4o完成:在用TabPFN這個模型構建一個預測未來3天漲跌的分類任務

通過akshare庫,獲取股票數據,并生成TabPFN這個模型 可以識別、處理的格式,寫一個完整的預處理示例,并構建一個預測未來 3 天股價漲跌的分類任務 用TabPFN這個模型構建一個預測未來 3 天股價漲跌的分類任務,進行預測并輸…

Device Mapper 機制

Device Mapper 機制詳解 Device Mapper(簡稱 DM)是 Linux 內核中的一套通用塊設備映射框架,為 LVM、加密磁盤、RAID 等提供底層支持。本文將詳細介紹 Device Mapper 的原理、實現、內核配置、常用工具、操作測試流程,并配以詳細的…

crackme006

crackme006 名稱值軟件名稱aLoNg3x.1.exe加殼方式無保護方式Serial編譯語言Delphi調試環境Win10 64位使用工具x32dbg,ida pro,PEid,DarkDe4破解日期2025-06-05 脫殼 1. 先用PEid查殼 查到無殼 尋找Serial 查詢到編程語言為Delphi 導出Delphi符號表信息到x32dbg&#xff0c…

Conda 創建新環境時報錯 HTTP 502,如何解決?

Conda 創建新環境時報錯 HTTP 502&#xff0c;如何解決&#xff1f; 最近在用 Conda 創建新環境時&#xff0c;突然遇到這樣一個錯誤&#xff1a; CondaHTTPError: HTTP 502 BAD GATEWAY for url <https://mirrors.westlake.edu.cn/ANACONDA/cloud/conda-forge/linux-64/r…

2025最全TS手寫題之partial/Omit/Pick/Exclude/Readonly/Required

隨著 TS 在工作中使用的越來越廣泛&#xff0c;面試的時候面試官也都會加上一兩個 TS 的問題來了解候選人對于 TS 的熟悉程度&#xff0c;其中就有不少手寫題目&#xff0c;比如筆者在字節的一次二面&#xff0c;面試官就問到了我如何實現一個 Pick&#xff0c;在小紅書的一面&…

基于江科大stm32屏幕驅動,實現OLED多級菜單(動畫效果),結構體鏈表實現(獨創源碼)

引言 在嵌入式系統中&#xff0c;用戶界面的設計往往直接影響到用戶體驗。本文將以STM32微控制器和OLED顯示屏為例&#xff0c;介紹如何實現一個多級菜單系統。該系統支持用戶通過按鍵導航菜單&#xff0c;執行相應操作&#xff0c;并提供平滑的滾動動畫效果。 本文設計了一個…

LLMs之StructuredOutput:大模型結構化輸出的簡介、常用方案、前沿框架之詳細攻略

LLMs之StructuredOutput&#xff1a;大模型結構化輸出的簡介、常用方案、前沿框架之詳細攻略 目錄 大模型結構化輸出的簡介 1、特點與難點 大模型結構化輸出的常用方案及對比 1、前沿框架&#xff1a;vLLM 與 XGrammar 大模型結構化輸出的案例應用 大模型結構化輸出的簡介…

Linux中shell流程控制語句

一、if條件控制 1.1 語法解讀 單路決策 - 單分支if語句樣式&#xff1a;if [ 條件 ]then指令fi特點&#xff1a;單一條件&#xff0c;只有一個輸出 雙路決策 - 雙分支if語句樣式&#xff1a;if [ 條件 ]then指令1else指令2fi特點&#xff1a;單一條件&#xff0c;兩個輸出 …

Python學習(8) ----- Python的類與對象

Python 中的類&#xff08;Class&#xff09;與對象&#xff08;Object&#xff09;是面向對象編程&#xff08;OOP&#xff09;的核心。我們可以通過“類是模板&#xff0c;對象是實例”來理解它們的關系。 &#x1f9f1; 一句話理解&#xff1a; 類就像“圖紙”&#xff0c;對…

數據結構-文件

文件是性質相同的記錄的集合。 記錄是文件中存取的基本單位&#xff0c;數據項是文件可使用的最小單位。 操作系統研究的文件是一維的無結構連續字符序列&#xff0c;數據庫中研究的文件是帶有結構的記錄集合。 文件在外存上的4種基本組織方式&#xff1a;順序、索引、散列、鏈…

前端開發面試題總結-CSS篇

文章目錄 CSS面試高頻問答1、CSS選擇器的優先級2、CSS3新特性3、如何垂直水平居中盒子4、什么是重繪和重排5、px/em/rem/vw有什么區別6、rem布局的原理7、如何設置比12px還要小的字體8、CSS中隱藏元素的方式有哪些 CSS面試高頻問答 1、CSS選擇器的優先級 2、CSS3新特性 3、如何…

Python如何給視頻添加音頻和字幕

在Python中&#xff0c;給視頻添加音頻和字幕可以使用電影文件處理庫MoviePy和字幕處理庫Subtitles。下面將詳細介紹如何使用這些庫來實現視頻的音頻和字幕添加&#xff0c;包括必要的代碼示例和詳細解釋。 環境準備 在開始之前&#xff0c;需要安裝以下Python庫&#xff1a;…

解決ubuntu20.04無法喚醒的問題的一種方法

解決ubuntu20.04無法喚醒的問題的一種方法 我更改了三個個地方&#xff0c;目前不清楚是哪個地方起的作用&#xff0c;也可能都起作用了 修改的第一個地方 步驟 1: 獲取 Swap 分區的 UUID 首先&#xff0c;你需要知道你的 swap 分區的 UUID。你可以使用以下命令來查找它&am…

【大廠機試題解法筆記】矩陣匹配

題目 從一個 N * M&#xff08;N ≤ M&#xff09;的矩陣中選出 N 個數&#xff0c;任意兩個數字不能在同一行或同一列&#xff0c;求選出來的 N 個數中第 K 大的數字的最小值是多少。 輸入描述 輸入矩陣要求&#xff1a;1 ≤ K ≤ N ≤ M ≤ 150 輸入格式 N M K N*M矩陣 輸…