xypriss-security
Version:
XyPriss Security is an advanced JavaScript security library designed for enterprise applications. It provides military-grade encryption, secure data structures, quantum-resistant cryptography, and comprehensive security utilities for modern web applicatio
535 lines (533 loc) • 18.4 kB
JavaScript
/**
* XyPrissSecurity - Ultra-Fast Predictive Cache
* Caching system with machine learning-based prediction
* Optimized for real-world applications
*/
class UltraFastCache {
constructor(maxSize = 10000, maxMemory = 100 * 1024 * 1024, compressionThreshold = 1024) {
this.cache = new Map();
this.currentMemory = 0;
// **PREDICTION ENGINE**
this.accessPatterns = new Map();
this.hotKeys = new Set();
this.coldKeys = new Set();
// **PERFORMANCE COUNTERS**
this.stats = {
hits: 0,
misses: 0,
evictions: 0,
predictions: 0,
correctPredictions: 0,
compressions: 0,
decompressions: 0,
totalOperations: 0,
avgAccessTime: 0,
};
this.maxSize = maxSize;
this.maxMemory = maxMemory;
this.compressionThreshold = compressionThreshold;
// Start background optimization
this.startOptimizationLoop();
}
/**
* **PERFORMANCE: Ultra-fast get with prediction**
*/
get(key) {
const startTime = Date.now();
this.stats.totalOperations++;
const entry = this.cache.get(key);
if (entry) {
// Check TTL
if (entry.ttl && Date.now() > entry.timestamp + entry.ttl) {
this.cache.delete(key);
this.currentMemory -= entry.size;
this.stats.misses++;
this.updateStats(startTime);
return null;
}
// Cache hit - update access pattern
this.updateAccessPattern(key, entry);
this.stats.hits++;
// Move to hot keys if frequently accessed
if (entry.accessCount > 5) {
// Reduced threshold
this.hotKeys.add(key);
this.coldKeys.delete(key);
}
this.updateStats(startTime);
// Decompress if needed
let value = entry.value;
if (entry.compressed) {
value = this.decompress(value);
this.stats.decompressions++;
}
return value;
}
// Cache miss
this.stats.misses++;
this.coldKeys.add(key);
this.updateStats(startTime);
return null;
}
/**
* **PERFORMANCE: Ultra-fast set with intelligent eviction**
*/
set(key, value, ttl) {
const startTime = Date.now();
this.stats.totalOperations++;
const size = this.estimateSize(value);
// Check if we need to evict entries
if (this.cache.size >= this.maxSize ||
this.currentMemory + size > this.maxMemory) {
this.intelligentEviction(size);
}
// Compress large values
let finalValue = value;
let compressed = false;
if (size > this.compressionThreshold) {
const compressedValue = this.compress(value);
const compressedSize = this.estimateSize(compressedValue);
// Only use compression if it saves significant space
if (compressedSize < size * 0.8) {
finalValue = compressedValue;
compressed = true;
this.stats.compressions++;
}
}
const now = Date.now();
const entry = {
value: finalValue,
timestamp: now,
accessCount: 1,
lastAccessed: now,
accessPattern: [now],
predictedNextAccess: now + (ttl || 300000), // Default 5 minutes
priority: this.calculatePriority(key),
size: this.estimateSize(finalValue),
compressed,
ttl,
};
// Remove old entry if it exists
const oldEntry = this.cache.get(key);
if (oldEntry) {
this.currentMemory -= oldEntry.size;
}
this.cache.set(key, entry);
this.currentMemory += entry.size;
// Initialize access pattern
this.initializeAccessPattern(key);
this.updateStats(startTime);
}
/**
* **UTILITY: Check if key exists**
*/
has(key) {
const entry = this.cache.get(key);
if (!entry)
return false;
// Check TTL
if (entry.ttl && Date.now() > entry.timestamp + entry.ttl) {
this.cache.delete(key);
this.currentMemory -= entry.size;
return false;
}
return true;
}
/**
* **UTILITY: Delete entry**
*/
delete(key) {
const entry = this.cache.get(key);
if (entry) {
this.cache.delete(key);
this.currentMemory -= entry.size;
this.hotKeys.delete(key);
this.coldKeys.delete(key);
this.accessPatterns.delete(key);
return true;
}
return false;
}
/**
* **PREDICTION ENGINE: Predict which keys will be accessed next**
*/
predictNextAccess(count = 10) {
const predictions = [];
for (const [key, pattern] of this.accessPatterns.entries()) {
if (this.cache.has(key)) {
// Only predict for existing keys
const probability = this.calculateAccessProbability(pattern);
predictions.push({ key, probability });
}
}
// Sort by probability and return top predictions
return predictions
.sort((a, b) => b.probability - a.probability)
.slice(0, count)
.map((p) => p.key);
}
/**
* **PREDICTION ENGINE: Warm cache with predicted entries**
*/
async warmCache(dataLoader) {
const predictions = this.predictNextAccess(10); // Reduced from 20
this.stats.predictions += predictions.length;
const warmingPromises = predictions.map(async (key) => {
if (!this.cache.has(key)) {
try {
const value = await dataLoader(key);
this.set(key, value);
this.stats.correctPredictions++;
}
catch (error) {
// Silently handle errors to avoid noise
}
}
});
await Promise.all(warmingPromises);
}
/**
* **INTELLIGENT EVICTION: Smart eviction based on access patterns**
*/
intelligentEviction(requiredSpace) {
const candidates = [];
for (const [key, entry] of this.cache.entries()) {
const score = this.calculateEvictionScore(entry);
candidates.push({ key, score });
}
// Sort by eviction score (lower = more likely to evict)
candidates.sort((a, b) => a.score - b.score);
let freedSpace = 0;
let evicted = 0;
const maxEvictions = Math.min(candidates.length, Math.ceil(this.cache.size * 0.1)); // Max 10% eviction
for (const candidate of candidates) {
if (freedSpace >= requiredSpace || evicted >= maxEvictions)
break;
const entry = this.cache.get(candidate.key);
if (entry) {
this.cache.delete(candidate.key);
this.currentMemory -= entry.size;
freedSpace += entry.size;
evicted++;
this.stats.evictions++;
// Clean up related data
this.hotKeys.delete(candidate.key);
this.coldKeys.delete(candidate.key);
this.accessPatterns.delete(candidate.key);
}
}
}
/**
* **PATTERN ANALYSIS: Calculate access probability**
*/
calculateAccessProbability(pattern) {
// Base probability on frequency (normalized)
let probability = Math.min(pattern.frequency / 10, 1.0);
// Adjust for trend
switch (pattern.trend) {
case "increasing":
probability *= 1.3;
break;
case "decreasing":
probability *= 0.7;
break;
}
// Apply confidence factor
probability *= pattern.confidence;
return Math.min(probability, 1.0);
}
/**
* **PATTERN ANALYSIS: Update access pattern for key**
*/
updateAccessPattern(key, entry) {
const now = Date.now();
entry.accessCount++;
entry.lastAccessed = now;
// Update access pattern (keep last 5 accesses)
entry.accessPattern.push(now);
if (entry.accessPattern.length > 5) {
entry.accessPattern.shift();
}
// Update prediction model
this.updatePredictionModel(key, entry);
// Predict next access time
entry.predictedNextAccess = this.predictNextAccessTime(entry.accessPattern);
}
/**
* **PATTERN ANALYSIS: Initialize access pattern for new key**
*/
initializeAccessPattern(key) {
this.accessPatterns.set(key, {
key: String(key),
frequency: 1,
periodicity: 0,
trend: "stable",
confidence: 0.5,
});
}
/**
* **MACHINE LEARNING: Update prediction model**
*/
updatePredictionModel(key, entry) {
const pattern = this.accessPatterns.get(key);
if (!pattern)
return;
// Calculate frequency (accesses per minute)
const timeSpan = entry.accessPattern.length > 1
? entry.accessPattern[entry.accessPattern.length - 1] -
entry.accessPattern[0]
: 60000; // Default 1 minute
pattern.frequency = (entry.accessPattern.length / timeSpan) * 60000;
// Determine trend (simplified)
if (entry.accessPattern.length >= 3) {
const recent = entry.accessPattern.slice(-2);
const older = entry.accessPattern.slice(0, 2);
if (recent.length === 2 && older.length === 2) {
const recentInterval = recent[1] - recent[0];
const olderInterval = older[1] - older[0];
if (recentInterval < olderInterval * 0.8) {
pattern.trend = "increasing";
pattern.confidence = Math.min(pattern.confidence + 0.1, 1.0);
}
else if (recentInterval > olderInterval * 1.2) {
pattern.trend = "decreasing";
pattern.confidence = Math.max(pattern.confidence - 0.05, 0.1);
}
else {
pattern.trend = "stable";
}
}
}
}
/**
* **PREDICTION: Predict next access time**
*/
predictNextAccessTime(accessPattern) {
if (accessPattern.length < 2) {
return Date.now() + 300000; // Default 5 minutes
}
// Calculate average interval
const intervals = [];
for (let i = 1; i < accessPattern.length; i++) {
intervals.push(accessPattern[i] - accessPattern[i - 1]);
}
const avgInterval = intervals.reduce((a, b) => a + b, 0) / intervals.length;
return accessPattern[accessPattern.length - 1] + avgInterval;
}
/**
* **OPTIMIZATION: Calculate priority for cache entry**
*/
calculatePriority(key) {
let priority = 1.0;
// Boost priority for hot keys
if (this.hotKeys.has(key)) {
priority *= 1.3;
}
return priority;
}
/**
* **OPTIMIZATION: Calculate eviction score**
*/
calculateEvictionScore(entry) {
const now = Date.now();
const age = now - entry.timestamp;
const timeSinceAccess = now - entry.lastAccessed;
// Lower score = more likely to evict
let score = entry.priority;
// Penalize old entries
score -= age / 3600000; // Age in hours
// Penalize recently unused entries
score -= timeSinceAccess / 1800000; // Time since access in 30-min units
// Boost score for frequently accessed entries
score += Math.log(entry.accessCount + 1);
// Penalize large entries
score -= entry.size / 10240; // Every 10KB
return Math.max(score, 0);
}
/**
* **COMPRESSION: Simple string compression using built-in methods**
*/
compress(value) {
try {
if (typeof value === "string" &&
value.length > this.compressionThreshold) {
// Simple compression using JSON + base64 (placeholder for real compression)
const compressed = btoa(encodeURIComponent(value));
if (compressed.length < value.length * 0.9) {
return compressed;
}
}
else if (typeof value === "object" && value !== null) {
const serialized = JSON.stringify(value);
if (serialized.length > this.compressionThreshold) {
const compressed = btoa(encodeURIComponent(serialized));
if (compressed.length < serialized.length * 0.9) {
return { __compressed: compressed };
}
}
}
}
catch (error) {
// Compression failed, return original value
}
return value;
}
/**
* **DECOMPRESSION: Simple decompression**
*/
decompress(value) {
try {
if (typeof value === "object" &&
value !== null &&
"__compressed" in value) {
const compressedData = value.__compressed;
const decompressed = decodeURIComponent(atob(compressedData));
return JSON.parse(decompressed);
}
else if (typeof value === "string") {
try {
const decompressed = decodeURIComponent(atob(value));
return decompressed;
}
catch {
return value;
}
}
}
catch (error) {
// Decompression failed, return as-is
}
return value;
}
/**
* **UTILITY: Estimate memory size of value**
*/
estimateSize(value) {
if (typeof value === "string") {
return value.length * 2; // UTF-16
}
if (typeof value === "number") {
return 8;
}
if (typeof value === "boolean") {
return 1;
}
if (value instanceof ArrayBuffer) {
return value.byteLength;
}
// Estimate for objects
try {
return JSON.stringify(value).length * 2;
}
catch {
return 1024; // Default estimate
}
}
/**
* **BACKGROUND OPTIMIZATION: Start optimization loop**
*/
startOptimizationLoop() {
this.optimizationTimer = setInterval(() => {
this.optimizeCache();
}, 60000); // Every minute (reduced frequency)
}
/**
* **BACKGROUND OPTIMIZATION: Optimize cache performance**
*/
optimizeCache() {
const now = Date.now();
// Remove expired entries
for (const [key, entry] of this.cache.entries()) {
// Remove expired TTL entries
if (entry.ttl && now > entry.timestamp + entry.ttl) {
this.cache.delete(key);
this.currentMemory -= entry.size;
this.hotKeys.delete(key);
this.coldKeys.delete(key);
this.accessPatterns.delete(key);
this.stats.evictions++;
}
// Remove very old predictions
else if (entry.predictedNextAccess < now - 600000) {
// 10 minutes past prediction
const timeSinceAccess = now - entry.lastAccessed;
if (timeSinceAccess > 1800000) {
// 30 minutes since last access
this.cache.delete(key);
this.currentMemory -= entry.size;
this.hotKeys.delete(key);
this.coldKeys.delete(key);
this.accessPatterns.delete(key);
this.stats.evictions++;
}
}
}
}
/**
* **PERFORMANCE: Update statistics**
*/
updateStats(startTime) {
const operationTime = Date.now() - startTime;
this.stats.avgAccessTime =
(this.stats.avgAccessTime * (this.stats.totalOperations - 1) +
operationTime) /
this.stats.totalOperations;
}
/**
* **MONITORING: Get comprehensive statistics**
*/
getStats() {
const hitRate = this.stats.hits + this.stats.misses > 0
? (this.stats.hits / (this.stats.hits + this.stats.misses)) *
100
: 0;
const predictionAccuracy = this.stats.predictions > 0
? (this.stats.correctPredictions / this.stats.predictions) * 100
: 0;
return {
...this.stats,
hitRate: hitRate.toFixed(1) + "%",
predictionAccuracy: predictionAccuracy.toFixed(1) + "%",
cacheSize: this.cache.size,
memoryUsage: this.currentMemory,
memoryUtilization: ((this.currentMemory / this.maxMemory) * 100).toFixed(1) + "%",
hotKeys: this.hotKeys.size,
coldKeys: this.coldKeys.size,
patterns: this.accessPatterns.size,
};
}
/**
* **UTILITY: Get all keys**
*/
keys() {
return Array.from(this.cache.keys());
}
/**
* **UTILITY: Get cache size**
*/
size() {
return this.cache.size;
}
/**
* **CLEANUP: Clear cache and free resources**
*/
clear() {
this.cache.clear();
this.accessPatterns.clear();
this.hotKeys.clear();
this.coldKeys.clear();
this.currentMemory = 0;
}
/**
* **CLEANUP: Destroy cache and free all resources**
*/
destroy() {
if (this.optimizationTimer) {
clearInterval(this.optimizationTimer);
this.optimizationTimer = undefined;
}
this.clear();
}
}
export { UltraFastCache };
//# sourceMappingURL=ultra-fast-cache.js.map