Skip to content

Commit 801965f

Browse files
committed
Agregar archivos faltantes del sistema de cache: CacheHealth, CacheManager, CacheStats, CachedClass, LRUCache
1 parent 1b21416 commit 801965f

5 files changed

Lines changed: 548 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.warmup.framework.cache;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
class CacheHealth {
10+
11+
public final boolean healthy;
12+
public final List<String> warnings;
13+
public final List<String> errors;
14+
public final Map<String, Object> metrics;
15+
16+
public CacheHealth(boolean healthy, List<String> warnings, List<String> errors, Map<String, Object> metrics) {
17+
this.healthy = healthy;
18+
this.warnings = Collections.unmodifiableList(new ArrayList<>(warnings));
19+
this.errors = Collections.unmodifiableList(new ArrayList<>(errors));
20+
this.metrics = Collections.unmodifiableMap(new HashMap<>(metrics));
21+
}
22+
23+
public boolean isHealthy() {
24+
return healthy && errors.isEmpty();
25+
}
26+
27+
public void printReport() {
28+
System.out.println("Cache Health Report:");
29+
System.out.println("Overall Status: " + (isHealthy() ? "HEALTHY" : "UNHEALTHY"));
30+
31+
if (!errors.isEmpty()) {
32+
System.out.println("\nErrors:");
33+
errors.forEach(error -> System.out.println(" " + error));
34+
}
35+
36+
if (!warnings.isEmpty()) {
37+
System.out.println("\nWarnings:");
38+
warnings.forEach(warning -> System.out.println(" " + warning));
39+
}
40+
41+
if (!metrics.isEmpty()) {
42+
System.out.println("\nMetrics:");
43+
metrics.forEach((key, value) -> System.out.println(" " + key + ": " + value));
44+
}
45+
}
46+
}
Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
package io.warmup.framework.cache;
2+
3+
import java.util.*;
4+
import java.util.concurrent.ConcurrentHashMap;
5+
import java.util.concurrent.atomic.AtomicInteger;
6+
import java.util.concurrent.atomic.AtomicLong;
7+
import java.util.concurrent.TimeUnit;
8+
import java.util.logging.Logger;
9+
10+
/**
11+
* O(1) Optimized Cache Manager with atomic counters, TTL caches, and cache invalidation.
12+
* Provides production-ready caching performance with comprehensive statistics.
13+
*/
14+
public class CacheManager {
15+
16+
private static final Logger log = Logger.getLogger(CacheManager.class.getName());
17+
18+
// O(1) Atomic Counters for Real-time Statistics
19+
private final AtomicInteger cachePuts = new AtomicInteger(0);
20+
private final AtomicInteger cacheGets = new AtomicInteger(0);
21+
private final AtomicInteger cacheHits = new AtomicInteger(0);
22+
private final AtomicInteger cacheMisses = new AtomicInteger(0);
23+
private final AtomicInteger cacheRemovals = new AtomicInteger(0);
24+
private final AtomicInteger cacheExpirations = new AtomicInteger(0);
25+
private final AtomicLong totalCacheOperations = new AtomicLong(0);
26+
27+
// O(1) TTL Caches - Cache Data (10s), Cache Stats (30s)
28+
private final Map<String, CacheEntry> cacheData = new ConcurrentHashMap<>();
29+
private final Map<String, Long> cacheDataExpiry = new ConcurrentHashMap<>();
30+
private static final long CACHE_DATA_TTL = TimeUnit.SECONDS.toMillis(10);
31+
32+
private final Map<String, Object> cacheStatsCache = new ConcurrentHashMap<>();
33+
private final Map<String, Long> cacheStatsExpiry = new ConcurrentHashMap<>();
34+
private static final long CACHE_STATS_TTL = TimeUnit.SECONDS.toMillis(30);
35+
36+
// O(1) Cache Invalidation Flags
37+
private volatile boolean cacheDataDirty = false;
38+
private volatile boolean cacheStatsDirty = false;
39+
40+
// O(1) Performance Monitoring
41+
private final AtomicLong totalCacheOperationTime = new AtomicLong(0);
42+
private volatile long startTime = System.currentTimeMillis();
43+
44+
// Backend storage for cache data
45+
private final Map<String, Object> backendStorage = new ConcurrentHashMap<>();
46+
47+
// Configuration
48+
private static final int MAX_CACHE_SIZE = 10000; // Maximum cache entries
49+
private static final int CLEANUP_THRESHOLD = 1000; // Trigger cleanup when threshold exceeded
50+
51+
/**
52+
* Default constructor
53+
*/
54+
public CacheManager() {
55+
log.info("CacheManager initialized with in-memory backend");
56+
}
57+
58+
// O(1) Optimized put operation with TTL caching
59+
public void put(String key, Object value) {
60+
long startTime = System.nanoTime();
61+
62+
cachePuts.incrementAndGet();
63+
totalCacheOperations.incrementAndGet();
64+
65+
// Backend storage operation (O(1))
66+
backendStorage.put(key, value);
67+
68+
// O(1) TTL cache storage
69+
cacheData.put(key, new CacheEntry(value, System.currentTimeMillis() + CACHE_DATA_TTL));
70+
cacheDataExpiry.put(key, System.currentTimeMillis() + CACHE_DATA_TTL);
71+
72+
// O(1) Cache invalidation
73+
cacheDataDirty = true;
74+
cacheStatsDirty = true;
75+
76+
// Trigger cleanup if needed
77+
if (cacheData.size() > CLEANUP_THRESHOLD) {
78+
cleanupExpiredEntries();
79+
}
80+
81+
long duration = System.nanoTime() - startTime;
82+
totalCacheOperationTime.addAndGet(duration);
83+
84+
log.info("Cache PUT: " + key + " = " + value);
85+
}
86+
87+
// O(1) Optimized get operation with TTL caching and hit/miss tracking
88+
public Object get(String key) {
89+
long startTime = System.nanoTime();
90+
91+
cacheGets.incrementAndGet();
92+
totalCacheOperations.incrementAndGet();
93+
94+
Object result = null;
95+
96+
// O(1) TTL cache check first
97+
if (isCacheValid(key, cacheData, cacheDataExpiry)) {
98+
CacheEntry entry = cacheData.get(key);
99+
if (entry != null && entry.value != null) {
100+
result = entry.value;
101+
cacheHits.incrementAndGet();
102+
103+
long duration = System.nanoTime() - startTime;
104+
totalCacheOperationTime.addAndGet(duration);
105+
106+
return result;
107+
}
108+
}
109+
110+
// Cache miss - try backend storage (O(1))
111+
result = backendStorage.get(key);
112+
113+
if (result != null) {
114+
cacheHits.incrementAndGet();
115+
// Refresh TTL cache
116+
cacheData.put(key, new CacheEntry(result, System.currentTimeMillis() + CACHE_DATA_TTL));
117+
cacheDataExpiry.put(key, System.currentTimeMillis() + CACHE_DATA_TTL);
118+
} else {
119+
cacheMisses.incrementAndGet();
120+
}
121+
122+
long duration = System.nanoTime() - startTime;
123+
totalCacheOperationTime.addAndGet(duration);
124+
125+
log.info("Cache GET: " + key + " = " + result);
126+
return result;
127+
}
128+
129+
// O(1) Optimized remove operation with cache invalidation
130+
public void remove(String key) {
131+
long startTime = System.nanoTime();
132+
133+
cacheRemovals.incrementAndGet();
134+
totalCacheOperations.incrementAndGet();
135+
136+
// Backend storage operation (O(1))
137+
backendStorage.remove(key);
138+
139+
// O(1) TTL cache removal
140+
CacheEntry removed = cacheData.remove(key);
141+
cacheDataExpiry.remove(key);
142+
143+
if (removed != null) {
144+
cacheDataDirty = true;
145+
cacheStatsDirty = true;
146+
}
147+
148+
long duration = System.nanoTime() - startTime;
149+
totalCacheOperationTime.addAndGet(duration);
150+
151+
log.info("Cache REMOVE: " + key);
152+
}
153+
154+
// O(1) Optimized info method with TTL caching
155+
public String getInfo() {
156+
String cacheKey = "cacheInfo";
157+
158+
// O(1) Cache check
159+
if (!cacheStatsDirty && isCacheValid(cacheKey, cacheStatsCache, cacheStatsExpiry)) {
160+
String cached = (String) cacheStatsCache.get(cacheKey);
161+
if (cached != null) return cached;
162+
}
163+
164+
StringBuilder info = new StringBuilder();
165+
info.append("CacheManager with O(1) Optimizations - ");
166+
info.append("Entries: ").append(cacheData.size());
167+
info.append(" | Backend: InMemory");
168+
info.append(" | Hit Rate: ").append(getHitRate()).append("%");
169+
info.append(" | Operations: ").append(totalCacheOperations.get());
170+
171+
String result = info.toString();
172+
173+
// O(1) Cache storage
174+
cacheStatsCache.put(cacheKey, result);
175+
cacheStatsExpiry.put(cacheKey, System.currentTimeMillis() + CACHE_STATS_TTL);
176+
cacheStatsDirty = false;
177+
178+
return result;
179+
}
180+
181+
// O(1) Helper method for cache validation
182+
private boolean isCacheValid(String key, Map<String, ?> cache, Map<String, Long> expiry) {
183+
Long expireTime = expiry.get(key);
184+
if (expireTime == null || System.currentTimeMillis() >= expireTime) {
185+
// Cache expired - count as expiration and clean up
186+
if (cache == cacheData) {
187+
cacheExpirations.incrementAndGet();
188+
cacheData.remove(key);
189+
cacheDataExpiry.remove(key);
190+
}
191+
return false;
192+
}
193+
return true;
194+
}
195+
196+
// O(1) Cleanup expired entries
197+
private void cleanupExpiredEntries() {
198+
long currentTime = System.currentTimeMillis();
199+
int expiredCount = 0;
200+
201+
Iterator<Map.Entry<String, Long>> iterator = cacheDataExpiry.entrySet().iterator();
202+
while (iterator.hasNext()) {
203+
Map.Entry<String, Long> entry = iterator.next();
204+
if (currentTime >= entry.getValue()) {
205+
cacheData.remove(entry.getKey());
206+
iterator.remove();
207+
expiredCount++;
208+
}
209+
}
210+
211+
if (expiredCount > 0) {
212+
cacheExpirations.addAndGet(expiredCount);
213+
cacheDataDirty = true;
214+
cacheStatsDirty = true;
215+
log.info("Cache cleanup: " + expiredCount + " expired entries removed");
216+
}
217+
}
218+
219+
// O(1) Atomic counter getters
220+
public int getCachePuts() {
221+
return cachePuts.get();
222+
}
223+
224+
public int getCacheGets() {
225+
return cacheGets.get();
226+
}
227+
228+
public int getCacheHits() {
229+
return cacheHits.get();
230+
}
231+
232+
public int getCacheMisses() {
233+
return cacheMisses.get();
234+
}
235+
236+
public int getCacheRemovals() {
237+
return cacheRemovals.get();
238+
}
239+
240+
public int getCacheExpirations() {
241+
return cacheExpirations.get();
242+
}
243+
244+
public long getTotalCacheOperations() {
245+
return totalCacheOperations.get();
246+
}
247+
248+
// O(1) Performance metrics
249+
public double getHitRate() {
250+
int total = cacheHits.get() + cacheMisses.get();
251+
return total > 0 ? (double) cacheHits.get() / total * 100 : 0.0;
252+
}
253+
254+
public double getAverageOperationTime() {
255+
long total = totalCacheOperations.get();
256+
return total > 0 ? (double) totalCacheOperationTime.get() / total / 1_000_000.0 : 0.0; // milliseconds
257+
}
258+
259+
public long getUptime() {
260+
return System.currentTimeMillis() - startTime;
261+
}
262+
263+
// O(1) Cache statistics
264+
public Map<String, Object> getCacheStatistics() {
265+
String cacheKey = "cacheStatistics";
266+
267+
// O(1) Cache check
268+
if (!cacheStatsDirty && isCacheValid(cacheKey, cacheStatsCache, cacheStatsExpiry)) {
269+
@SuppressWarnings("unchecked")
270+
Map<String, Object> cached = (Map<String, Object>) cacheStatsCache.get(cacheKey);
271+
if (cached != null) return cached;
272+
}
273+
274+
Map<String, Object> stats = new HashMap<>();
275+
stats.put("cachePuts", cachePuts.get());
276+
stats.put("cacheGets", cacheGets.get());
277+
stats.put("cacheHits", cacheHits.get());
278+
stats.put("cacheMisses", cacheMisses.get());
279+
stats.put("cacheRemovals", cacheRemovals.get());
280+
stats.put("cacheExpirations", cacheExpirations.get());
281+
stats.put("totalOperations", totalCacheOperations.get());
282+
stats.put("hitRate", getHitRate());
283+
stats.put("averageOperationTimeMs", getAverageOperationTime());
284+
stats.put("uptimeMs", getUptime());
285+
stats.put("currentCacheSize", cacheData.size());
286+
stats.put("backendCacheType", "InMemory");
287+
288+
// O(1) Cache storage
289+
cacheStatsCache.put(cacheKey, stats);
290+
cacheStatsExpiry.put(cacheKey, System.currentTimeMillis() + CACHE_STATS_TTL);
291+
cacheStatsDirty = false;
292+
293+
return stats;
294+
}
295+
296+
// O(1) Force cache invalidation
297+
public void clearAllCaches() {
298+
cacheData.clear();
299+
cacheDataExpiry.clear();
300+
cacheStatsCache.clear();
301+
cacheStatsExpiry.clear();
302+
303+
cacheDataDirty = false;
304+
cacheStatsDirty = false;
305+
306+
log.info("All caches cleared");
307+
}
308+
309+
// O(1) Force refresh all cached data
310+
public void refreshCache() {
311+
clearAllCaches();
312+
// Optionally clear backend cache
313+
// This would need to be implemented in the backend cache service
314+
}
315+
316+
// Internal CacheEntry class
317+
private static class CacheEntry {
318+
final Object value;
319+
final long expiryTime;
320+
321+
CacheEntry(Object value, long expiryTime) {
322+
this.value = value;
323+
this.expiryTime = expiryTime;
324+
}
325+
326+
boolean isExpired() {
327+
return System.currentTimeMillis() >= expiryTime;
328+
}
329+
}
330+
}

0 commit comments

Comments
 (0)