JavaScript is disabled. Some features may not work.
content-hash-cache-pattern — ★ 220.5K GitHub Stars — Install Guide | SkillsNav
🇺🇸 English🇨🇳 中文
SkillsNav
Home

content-hash-cache-pattern

★ 220K repogenerationN/AIntermediateClaude
🤖 AI Summary

This skill wraps expensive file processing functions (PDF parsing, text extraction, image analysis) with a cache that uses SHA-256 content hashes as keys instead of file paths, so cached results survive file moves/renames and automatically invalidate when content changes.

How to Install

Claude Code:
git clone --depth 1 https://github.com/affaan-m/ECC.git && cp ECC/skills/content-hash-cache-pattern ~/.claude/skills/content-hash-cache-pattern -r
# Content-Hash File Cache Pattern Cache expensive file processing results (PDF parsing, text extraction, image analysis) using SHA-256 content hashes as cache keys. Unlike path-based caching, this approach survives file moves/renames and auto-invalidates when content changes. ## When to Activate - Building file processing pipelines (PDF, images, text extraction) - Processing cost is high and same files are processed repeatedly - Need a `--cache/--no-cache` CLI option - Want to add caching to existing pure functions without modifying them ## Core Pattern ### 1. Content-Hash Based Cache Key Use file content (not path) as the cache key: ```python import hashlib from pathlib import Path _HASH_CHUNK_SIZE = 65536 # 64KB chunks for large files def compute_file_hash(path: Path) -> str: """SHA-256 of file contents (chunked for large files).""" if not path.is_file(): raise FileNotFoundError(f"File not found: {path}") sha256 = hashlib.sha256() with open(path, "rb") as f: while True: chunk = f.read(_HASH_CHUNK_SIZE) if not chunk: break sha256.update(chunk) return sha256.hexdigest() ``` **Why content hash?** File rename/move = cache hit. Content change = automatic invalidation. No index file needed. ### 2. Frozen Dataclass for Cache Entry ```python from dataclasses import dataclass @dataclass(frozen=True, slots=True) class CacheEntry: file_hash: str source_path: str document: ExtractedDocument # The cached result ``` ### 3. File-Based Cache Storage Each cache entry is stored as `{hash}.json` — O(1) lookup by hash, no index file required. ```python import json from typing import Any def write_cache(cache_dir: Path, entry: CacheEntry) -> None: cache_dir.mkdir(parents=True, exist_ok=True) cache_file = cache_dir / f"{entry.file_hash}.json" data = serialize_entry(entry) cache_file.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8") def read_cache(cache_dir: Path, file_hash: str) -> CacheEntry | None: cache_file = cache_dir / f"{file_hash}.json" if not cache_file.is_file(): return None try: raw = cache_file.read_text(encoding="utf-8") data = json.loads(raw) return deserialize_entry(data) except (json.JSONDecodeError, ValueError, KeyError): return None # Treat corruption as cache miss ``` ### 4. Service Layer Wrapper (SRP) Keep the processing function pure. Add caching as a separate service layer. ```python def extract_with_cache( file_path: Path, *, cache_enabled: bool = True, cache_dir: Path = Path(".cache"), ) -> ExtractedDocument: """Service layer: cache check -> extraction -> cache write.""" if not cache_enabled: return extract_text(file_path) # Pure function, no cache knowledge file_hash = compute_file_hash(file_path) # Check cache cached = read_cache(cache_dir, file_hash) if cached is not None:

Details

Category Coding → generation
Sourceaffaan-m/ECC
SKILL.mdView on GitHub →
Repo Stars★ 220.5K
Est. per SkillN/A (shared across 121 skills from this repo)
DifficultyIntermediate
Risk LevelN/A

Related Skills

Works Well With

Skills from the same repository — often designed to work together