CachePerformance.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
cache /
CachePerformance.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package br.ufrgs.inf.prosoft.cache;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author romulo
*/
public class CachePerformance {
private static final String CACHE_EVENTS = System.getenv("CACHE_EVENTS") != null ? System.getenv("CACHE_EVENTS") : null;
private int misses;
private int additions;
private double bytesAdded;
private int hits;
private double bytesHit;
private int invalidations;
private double bytesInvalidated;
private int maximumSize;
private final String name;
public CachePerformance() {
this("AnonymousCache");
}
public CachePerformance(String name) {
this.name = name;
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
Logger.getLogger(CachePerformance.class.getName()).log(Level.INFO, "printing caching metrics");
System.out.println(CachePerformance.this.name + ": " + CachePerformance.this.toLongString());
}
});
}
public void reduce(CachePerformance cachingPerformance) {
this.misses += cachingPerformance.misses;
this.additions += cachingPerformance.additions;
this.bytesAdded += cachingPerformance.bytesAdded;
this.hits += cachingPerformance.hits;
this.bytesHit += cachingPerformance.bytesHit;
this.invalidations += cachingPerformance.invalidations;
this.bytesInvalidated += cachingPerformance.bytesInvalidated;
this.maximumSize = Math.max(this.maximumSize, cachingPerformance.maximumSize);
}
public void registerEvent(EventType type, String identifier, int size) {
switch (type) {
case HIT:
this.hits++;
this.bytesHit += size;
break;
case MISS:
this.misses++;
break;
case ADDITION:
this.additions++;
this.bytesAdded += size;
break;
case INVALIDATION:
this.invalidations++;
this.bytesInvalidated += size;
break;
default:
throw new AssertionError(type.name());
}
CacheEvent cacheEvent = new CacheEvent(type, this.name, identifier, size);
logCacheEvent(cacheEvent);
}
public void registerEvent(EventType event) {
registerEvent(event, null, 0);
}
public void registerEvent(EventType event, int size) {
registerEvent(event, null, size);
}
public void registerEvent(EventType event, String identifier) {
registerEvent(event, identifier, 0);
}
public void registerEntry() {
this.maximumSize++;
}
public void registerSize(int size) {
this.maximumSize = Math.max(this.maximumSize, size);
}
public long getRoundedHitRatio() {
return Math.round(getHitRatio());
}
public double getHitRatio() {
return this.hits * 100.0 / (this.hits + this.misses);
}
public double getByteHitRatio() {
return 100.0 * (this.bytesHit / (this.bytesHit + (this.bytesHit / this.hits) * this.misses));
}
public String needInvalidation() {
return this.invalidations > 0 ? "yes" : "no";
}
public static int calculateObjectSize(Object object) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
objectOutputStream.writeObject(object);
byte[] toByteArray = outputStream.toByteArray();
return toByteArray.length;
} catch (IOException ex) {
System.err.println("[Cache] size exception: " + ex);
}
return 0;
}
private void logCacheEvent(CacheEvent cacheEvent) {
if (CACHE_EVENTS == null) {
return;
}
try (FileWriter fileWriter = new FileWriter(CACHE_EVENTS, true)) {
fileWriter.write(cacheEvent.toString() + "\n");
} catch (IOException ex) {
}
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("H").append(this.hits);
stringBuilder.append(" M").append(this.misses);
stringBuilder.append(" I").append(this.invalidations);
stringBuilder.append(" S").append(this.maximumSize);
return stringBuilder.toString();
}
public String toLongString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Hits: ").append(this.hits);
stringBuilder.append("; Misses: ").append(this.misses);
stringBuilder.append("; Hit Ratio: ").append(getHitRatio());
stringBuilder.append("%; Invalidations: ").append(this.invalidations);
stringBuilder.append("; Maximum Size: ").append(this.maximumSize);
return stringBuilder.toString();
}
}