Files
modelTesting/outputs/qwen3-coder-30b-6bit-mlx-lfu.py
T
adminandClaude 0c79a997f5 Capture kat-coder + qwen3-coder-30b outputs (5 prompts each, API-run, NOT graded yet)
Via tools/grade_run.py against LM Studio (load -> all prompts -> unload -> verify).
kat-coder:      lfu/tts/webhook/automation/rust  (lfu has a real SyntaxError: 'self._ bump_freq')
qwen3-coder-30b: lfu/tts/webhook/automation/rust  (all 4 py parse clean; terse ~2k tok outputs)
Grading deferred to a later session (capture-only mode).

Script hardening:
  - --resident / --unload-all commands (read loaded_instances, POST unload, verify)
  - MEMORY GUARD: aborts if a different model is resident (never stack 30GB models)
  - TTFT self-discovery dump (LM Studio returns empty stats non-streaming;
    fix next session: switch to /api/v1/chat stream:true -> chat.end result.stats)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 19:22:41 -07:00

350 lines
12 KiB
Python

import asyncio
import time
import weakref
from dataclasses import dataclass, field
from typing import Optional, Dict, Any, List, Set, Tuple
from collections import OrderedDict
import threading
from concurrent.futures import ThreadPoolExecutor
@dataclass
class CacheEntry:
"""Represents a cache entry with value, frequency, and TTL."""
value: Any
freq: int = 0
ttl: Optional[float] = None # Unix timestamp when it expires
created_at: float = field(default_factory=time.time)
accessed_at: float = field(default_factory=time.time)
@dataclass
class Transaction:
"""Represents a transaction context for atomic operations."""
cache: 'LFUCache'
_writes: Dict[str, CacheEntry] = field(default_factory=dict)
_deletes: Set[str] = field(default_factory=set)
_committed: bool = False
_rolled_back: bool = False
def get(self, key: str) -> Optional[Any]:
"""Get value from transaction or global cache."""
if self._rolled_back:
raise RuntimeError("Transaction already rolled back")
if key in self._deletes:
return None
if key in self._writes:
return self._writes[key].value
return self.cache.get(key)
def put(self, key: str, value: Any, ttl_seconds: Optional[float] = None) -> None:
"""Put value in transaction."""
if self._rolled_back:
raise RuntimeError("Transaction already rolled back")
self._writes[key] = CacheEntry(
value=value,
freq=0,
ttl=(time.time() + ttl_seconds) if ttl_seconds is not None else None
)
self._deletes.discard(key)
def delete(self, key: str) -> None:
"""Delete key in transaction."""
if self._rolled_back:
raise RuntimeError("Transaction already rolled back")
self._deletes.add(key)
self._writes.pop(key, None)
async def commit(self) -> None:
"""Commit transaction to global cache."""
if self._committed or self._rolled_back:
return
async with self.cache._lock:
for key, entry in self._writes.items():
self.cache._put_internal(key, entry)
for key in self._deletes:
self.cache._delete_internal(key)
self._committed = True
async def rollback(self) -> None:
"""Rollback transaction."""
if self._rolled_back:
return
self._rolled_back = True
self._writes.clear()
self._deletes.clear()
class LFUCache:
"""In-Memory Concurrent LFU Cache with Async TTL Eviction and Atomic Transactions."""
def __init__(self, capacity: int = 128):
self.capacity = capacity
self._cache: Dict[str, CacheEntry] = {}
self._freq_buckets: Dict[int, OrderedDict[str, None]] = {} # freq -> ordered keys
self._key_to_freq: Dict[str, int] = {} # key -> freq
self._lock = asyncio.Lock()
self._evictor_task: Optional[asyncio.Task] = None
self._evictor_running = False
self._executor = ThreadPoolExecutor(max_workers=1)
def begin_transaction(self) -> Transaction:
"""Begin a new transaction."""
return Transaction(self)
def _get_freq_bucket(self, freq: int) -> OrderedDict[str, None]:
"""Get or create frequency bucket."""
if freq not in self._freq_buckets:
self._freq_buckets[freq] = OrderedDict()
return self._freq_buckets[freq]
def _update_freq(self, key: str) -> None:
"""Update frequency of a key."""
if key not in self._key_to_freq:
return
old_freq = self._key_to_freq[key]
new_freq = old_freq + 1
self._key_to_freq[key] = new_freq
# Remove from old bucket
old_bucket = self._get_freq_bucket(old_freq)
if key in old_bucket:
del old_bucket[key]
# Add to new bucket
new_bucket = self._get_freq_bucket(new_freq)
new_bucket[key] = None
def _delete_internal(self, key: str) -> None:
"""Delete key from internal structures."""
if key in self._cache:
entry = self._cache[key]
freq = self._key_to_freq.pop(key, 0)
bucket = self._get_freq_bucket(freq)
if key in bucket:
del bucket[key]
del self._cache[key]
def _put_internal(self, key: str, entry: CacheEntry) -> None:
"""Internal put operation."""
# Update frequency
if key in self._cache:
old_entry = self._cache[key]
freq = self._key_to_freq.pop(key, 0)
bucket = self._get_freq_bucket(freq)
if key in bucket:
del bucket[key]
else:
# New entry
self._key_to_freq[key] = 0
# Update cache and frequency tracking
self._cache[key] = entry
self._update_freq(key)
# Evict if needed
if len(self._cache) > self.capacity:
self._evict_lfu()
def _evict_lfu(self) -> None:
"""Evict least frequently used item."""
# Find the lowest frequency bucket with items
min_freq = min(self._freq_buckets.keys()) if self._freq_buckets else 0
bucket = self._get_freq_bucket(min_freq)
if bucket:
# Remove oldest item in the lowest frequency bucket
key = next(iter(bucket))
self._delete_internal(key)
def _is_expired(self, entry: CacheEntry) -> bool:
"""Check if an entry is expired."""
return entry.ttl is not None and time.time() > entry.ttl
def _cleanup_expired(self) -> None:
"""Cleanup expired entries."""
expired_keys = []
for key, entry in self._cache.items():
if self._is_expired(entry):
expired_keys.append(key)
for key in expired_keys:
self._delete_internal(key)
async def get(self, key: str) -> Optional[Any]:
"""Get value by key with O(1) time complexity."""
async with self._lock:
# Cleanup expired entries
self._cleanup_expired()
if key not in self._cache:
return None
entry = self._cache[key]
# Check if expired
if self._is_expired(entry):
self._delete_internal(key)
return None
# Update access time and frequency
entry.accessed_at = time.time()
self._update_freq(key)
return entry.value
async def put(self, key: str, value: Any, ttl_seconds: Optional[float] = None) -> None:
"""Put key-value with TTL in cache."""
async with self._lock:
# Cleanup expired entries
self._cleanup_expired()
entry = CacheEntry(
value=value,
freq=0,
ttl=(time.time() + ttl_seconds) if ttl_seconds is not None else None
)
self._put_internal(key, entry)
async def delete(self, key: str) -> None:
"""Delete a key from cache."""
async with self._lock:
self._delete_internal(key)
def start_evictor(self) -> None:
"""Start the background evictor task."""
if self._evictor_running:
return
self._evictor_running = True
self._evictor_task = asyncio.create_task(self._evictor_loop())
def stop_evictor(self) -> None:
"""Stop the background evictor task."""
self._evictor_running = False
if self._evictor_task:
self._evictor_task.cancel()
async def _evictor_loop(self) -> None:
"""Background task to periodically evict expired entries."""
while self._evictor_running:
try:
await asyncio.sleep(1.0)
# Run cleanup in thread pool to avoid blocking
loop = asyncio.get_event_loop()
await loop.run_in_executor(self._executor, self._cleanup_expired)
except asyncio.CancelledError:
break
except Exception:
pass # Ignore errors in evictor loop
async def main():
"""Run unit tests for the LFUCache implementation."""
print("Starting LFU Cache Tests...")
# Test 1: O(1) LFU eviction order
print("\n1. Testing O(1) LFU eviction...")
cache = LFUCache(capacity=3)
# Put 4 items, should evict the least frequently used
await cache.put("a", "value_a")
await cache.put("b", "value_b")
await cache.put("c", "value_c")
# Access "a" to increase its frequency
await cache.get("a")
await cache.put("d", "value_d") # Should evict "b" (least frequent)
assert await cache.get("a") == "value_a", "Should still have 'a'"
assert await cache.get("b") is None, "Should have evicted 'b'"
assert await cache.get("c") == "value_c", "Should still have 'c'"
assert await cache.get("d") == "value_d", "Should have 'd'"
print("✓ LFU eviction works correctly")
# Test 2: Lazy TTL vs. Background Async Sweep
print("\n2. Testing TTL eviction...")
cache = LFUCache(capacity=10)
# Put with short TTL
await cache.put("short", "value", ttl_seconds=0.1)
await cache.put("long", "value2", ttl_seconds=1.0)
# Should have both entries
assert await cache.get("short") == "value"
assert await cache.get("long") == "value2"
# Wait for short TTL to expire
await asyncio.sleep(0.15)
# Short should be gone, long should still be there
assert await cache.get("short") is None, "Short TTL should have expired"
assert await cache.get("long") == "value2", "Long TTL should still be valid"
print("✓ TTL eviction works correctly")
# Test 3: Transaction commit visibility vs rollback
print("\n3. Testing transaction isolation...")
cache = LFUCache(capacity=10)
# Start transaction
tx = cache.begin_transaction()
# Write to transaction
tx.put("tx_key", "tx_value")
assert tx.get("tx_key") == "tx_value", "Transaction should see its own writes"
# Global cache should not see transaction changes
assert await cache.get("tx_key") is None, "Global cache should not see uncommitted changes"
# Commit transaction
await tx.commit()
# Global cache should now see changes
assert await cache.get("tx_key") == "tx_value", "Global cache should see committed changes"
# Start another transaction
tx2 = cache.begin_transaction()
tx2.put("tx_key2", "tx_value2")
# Rollback
await tx2.rollback()
# Should not see rolled back changes
assert await cache.get("tx_key2") is None, "Should not see rolled back changes"
print("✓ Transaction isolation works correctly")
# Test 4: Stress test with concurrent tasks
print("\n4. Testing concurrent access...")
cache = LFUCache(capacity=50)
async def worker(worker_id: int, num_ops: int):
for i in range(num_ops):
key = f"worker_{worker_id}_key_{i}"
await cache.put(key, f"value_{worker_id}_{i}")
value = await cache.get(key)
assert value is not None, f"Worker {worker_id} failed to get value for key {key}"
# Run 50 concurrent tasks
tasks = [worker(i, 10) for i in range(50)]
await asyncio.gather(*tasks)
# Verify all keys are present
for i in range(50):
for j in range(10):
key = f"worker_{i}_key_{j}"
value = await cache.get(key)
assert value is not None, f"Key {key} should exist"
print("✓ Concurrent access works correctly")
# Cleanup
cache.stop_evictor()
print("\nAll tests passed!")
if __name__ == "__main__":
asyncio.run(main())