/** * Access Pattern Tracker for Intelligent Tiering * * This module provides advanced access pattern tracking for the postgres.do * tiered storage architecture. It enables intelligent promotion/demotion * decisions based on: * * - Exponential decay scoring (configurable half-life) * - Recency-weighted frequency calculation * - Working set estimation using sliding window * - Page correlation detection using co-access matrix * * The tracker is designed to work with Cloudflare Durable Objects and supports * serialization for hibernation. * * @module @dotdo/postgres-shared/access-pattern-tracker */ import type { AccessStats, StorageTier } from './storage-policy.js'; /** * Configuration for the access pattern tracker */ export interface AccessPatternConfig { /** * Half-life for exponential decay in milliseconds. * After this time, the access score is halved. * Default: 5 minutes (300,000ms) */ decayHalfLifeMs: number; /** * Sliding window size in milliseconds for working set estimation. * Default: 1 minute (60,000ms) */ slidingWindowMs: number; /** * Maximum time gap between accesses to be considered correlated. * Pages accessed within this time of each other are correlated. * Default: 100ms */ correlationWindowMs: number; /** * Minimum correlation strength to track (0-1). * Correlations below this are pruned. * Default: 0.1 */ minCorrelationStrength: number; /** * Maximum number of correlations to track per page. * Default: 50 */ maxCorrelationsPerPage: number; /** * Recency bonus weight (0-1). * Higher values give more weight to recent accesses. * Default: 0.3 */ recencyWeight: number; /** * Maximum number of pages to track. * Oldest/lowest-scored pages are evicted when limit is reached. * Default: 10,000 */ maxTrackedPages: number; /** * Interval for pruning stale data in milliseconds. * Default: 5 minutes (300,000ms) */ pruneIntervalMs: number; } /** * Default configuration for the access pattern tracker */ export declare const DEFAULT_ACCESS_PATTERN_CONFIG: AccessPatternConfig; /** * Sparse co-access matrix entry for correlation tracking */ interface CoAccessEntry { /** Target page ID */ targetPageId: string; /** Number of co-accesses */ coAccessCount: number; /** Last co-access timestamp */ lastCoAccessTime: number; } /** * Serialized state for DO hibernation */ export interface SerializedAccessPatternState { version: number; config: AccessPatternConfig; pages: Array<{ pageId: string; firstAccessTime: number; lastAccessTime: number; totalAccessCount: number; recentAccessTimes: number[]; decayedScore: number; lastScoreUpdate: number; currentTier?: StorageTier; sizeBytes?: number; }>; correlations: Array<{ sourcePageId: string; entries: CoAccessEntry[]; }>; workingSet: { windowAccessTimes: number[]; uniquePagesInWindow: string[]; }; lastPruneTime: number; } /** * Result of scoring a page */ export interface PageScore { /** Page identifier */ pageId: string; /** Combined score (decay + recency) */ score: number; /** Decay component of the score */ decayScore: number; /** Recency bonus component */ recencyBonus: number; /** Access count within the sliding window */ windowAccessCount: number; /** Total access count */ totalAccessCount: number; } /** * Working set estimation result */ export interface WorkingSetEstimate { /** Number of unique pages accessed in the window */ uniquePageCount: number; /** Total accesses in the window */ totalAccessCount: number; /** Page IDs in the working set */ pageIds: string[]; /** Estimated size in bytes (if size data available) */ estimatedSizeBytes?: number; /** Window duration in milliseconds */ windowMs: number; } /** * Correlated pages result */ export interface CorrelatedPages { /** Source page ID */ sourcePageId: string; /** Correlated pages sorted by strength (strongest first) */ correlations: Array<{ pageId: string; strength: number; coAccessCount: number; lastCoAccessTime: number; }>; } /** * Access Pattern Tracker for intelligent tiering decisions * * This class tracks page access patterns to enable intelligent promotion * and demotion decisions in the tiered storage system. * * Features: * - Exponential decay scoring with configurable half-life * - Recency-weighted frequency calculation * - Working set estimation using sliding window * - Page correlation detection using sparse co-access matrix * - Serialization support for DO hibernation * * @example * ```typescript * const tracker = new AccessPatternTracker() * * // Record page accesses * tracker.recordAccess('page-1') * tracker.recordAccess('page-2') * * // Get page scores for tiering decisions * const scores = tracker.getPageScores() * console.log(scores[0]) // Highest scored page * * // Get working set estimate * const workingSet = tracker.getWorkingSetEstimate() * console.log(`Working set: ${workingSet.uniquePageCount} pages`) * * // Get correlated pages for batch promotion * const correlated = tracker.getCorrelatedPages('page-1') * console.log(`Pages to promote with page-1:`, correlated.correlations) * * // Serialize for hibernation * const state = tracker.serialize() * * // Restore from hibernation * const restoredTracker = AccessPatternTracker.deserialize(state) * ``` */ export declare class AccessPatternTracker { private config; private pages; private correlations; private recentAccessedPageIds; private lastPruneTime; /** * Create a new access pattern tracker * * @param config - Optional configuration overrides */ constructor(config?: Partial); /** * Record a page access * * @param pageId - The page identifier * @param timestamp - Access timestamp (defaults to now) * @param sizeBytes - Optional page size in bytes * @param currentTier - Optional current storage tier */ recordAccess(pageId: string, timestamp?: number, sizeBytes?: number, currentTier?: StorageTier): void; /** * Get the score for a specific page * * @param pageId - The page identifier * @param currentTime - Current timestamp (defaults to now) * @returns Page score or null if page not tracked */ getPageScore(pageId: string, currentTime?: number): PageScore | null; /** * Get scores for all tracked pages, sorted by score descending * * @param currentTime - Current timestamp (defaults to now) * @param limit - Maximum number of results (default: all) * @returns Array of page scores sorted by score descending */ getPageScores(currentTime?: number, limit?: number): PageScore[]; /** * Get access statistics for a page (compatible with TierPolicy interface) * * @param pageId - The page identifier * @param currentTime - Current timestamp (defaults to now) * @returns Access statistics or null if page not tracked */ getAccessStats(pageId: string, currentTime?: number): AccessStats | null; /** * Get working set estimate based on sliding window * * @param currentTime - Current timestamp (defaults to now) * @returns Working set estimation */ getWorkingSetEstimate(currentTime?: number): WorkingSetEstimate; /** * Get pages correlated with a given page * * Pages that are frequently accessed together (within the correlation window) * are considered correlated. This enables batch promotion of related pages. * * @param pageId - The source page identifier * @param minStrength - Minimum correlation strength to include (default: from config) * @returns Correlated pages sorted by strength */ getCorrelatedPages(pageId: string, minStrength?: number): CorrelatedPages; /** * Get pages that should be promoted together with the given page * * Returns the page itself plus all strongly correlated pages. * * @param pageId - The page being promoted * @param correlationThreshold - Minimum correlation strength (default: 0.5) * @returns Array of page IDs to promote together */ getPagesToPromoteTogether(pageId: string, correlationThreshold?: number): string[]; /** * Update the current tier for a page * * @param pageId - The page identifier * @param tier - The new storage tier */ updatePageTier(pageId: string, tier: StorageTier): void; /** * Get the current tier for a page * * @param pageId - The page identifier * @returns Current tier or undefined if not tracked */ getPageTier(pageId: string): StorageTier | undefined; /** * Check if a page is being tracked * * @param pageId - The page identifier * @returns True if the page is tracked */ isTracked(pageId: string): boolean; /** * Get the number of tracked pages * * @returns Number of tracked pages */ getTrackedPageCount(): number; /** * Get the current configuration * * @returns A copy of the current configuration */ getConfig(): AccessPatternConfig; /** * Serialize the tracker state for DO hibernation * * @returns Serialized state that can be stored and restored */ serialize(): SerializedAccessPatternState; /** * Deserialize and restore tracker state from DO hibernation * * @param state - Serialized state from serialize() * @returns Restored AccessPatternTracker instance */ static deserialize(state: SerializedAccessPatternState): AccessPatternTracker; /** * Remove a page from tracking * * @param pageId - The page identifier to remove */ removePage(pageId: string): void; /** * Clear all tracking data */ clear(): void; /** * Calculate exponential decay factor * * @param timeSinceAccess - Time since last access in milliseconds * @returns Decay factor (0 to 1) */ private calculateDecayFactor; /** * Update the decayed score for a page with lazy evaluation * * @param pageData - The page data to update * @param currentTime - Current timestamp */ private updateDecayedScore; /** * Calculate the full page score * * @param pageData - The page data * @param currentTime - Current timestamp * @returns Calculated page score */ private calculatePageScore; /** * Track page access for correlation detection * * @param pageId - The page that was just accessed * @param timestamp - Access timestamp */ private trackForCorrelation; /** * Record a co-access between two pages * * @param sourcePageId - The source page * @param targetPageId - The target page * @param timestamp - Co-access timestamp */ private recordCoAccess; /** * Prune stale data to manage memory usage * * @param currentTime - Current timestamp */ private prune; } /** * Create an access pattern tracker with preset configurations * * @param preset - Preset name or 'default' * @param overrides - Optional configuration overrides * @returns Configured AccessPatternTracker */ export declare function createAccessPatternTracker(preset?: 'default' | 'high-frequency' | 'long-term' | 'correlation-focused', overrides?: Partial): AccessPatternTracker; export {}; //# sourceMappingURL=access-pattern-tracker.d.ts.map