/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.persistence.proxy;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* INTERNAL: A transactional storage cache implementation. The cache
* uses the transactions identity map to lookup objects and stores its
* cache entries directly on the PersistentIFs.
*/
public class StatisticsCache implements StorageCacheIF {
// Define a logging category.
static Logger log = LoggerFactory.getLogger(StatisticsCache.class.getName());
protected int total_o;
protected int total_f;
protected int hits_o;
protected int hits_f;
protected int misses_o;
protected int misses_f;
protected int dump_interval = 100;
protected String name;
protected StorageCacheIF pcache;
StatisticsCache(String name, StorageCacheIF parent_cache, int dump_interval) {
this.name = name;
this.pcache = parent_cache;
this.dump_interval = dump_interval;
}
// -----------------------------------------------------------------------------
// StorageCacheIF implementation
// -----------------------------------------------------------------------------
public AccessRegistrarIF getRegistrar() {
return pcache.getRegistrar();
}
public void close() {
pcache.close();
}
public boolean exists(StorageAccessIF access, IdentityIF identity) {
total_o++;
if (pcache.isObjectLoaded(identity)) {
hits_o++;
} else {
misses_o++;
}
if (total_o % dump_interval == 0)
dump();
return pcache.exists(access, identity);
}
public Object getValue(StorageAccessIF access, IdentityIF identity, int field) {
total_f++;
if (pcache.isFieldLoaded(identity, field)) {
hits_f++;
} else {
misses_f++;
}
if (total_f % dump_interval == 0)
dump();
return pcache.getValue(access, identity, field);
}
public boolean isObjectLoaded(IdentityIF identity) {
return pcache.isObjectLoaded(identity);
}
public boolean isFieldLoaded(IdentityIF identity, int field) {
return pcache.isFieldLoaded(identity, field);
}
public void registerEviction() {
pcache.registerEviction();
}
public void releaseEviction() {
pcache.releaseEviction();
}
public void evictIdentity(IdentityIF identity, boolean notifyCluster) {
pcache.evictIdentity(identity, notifyCluster);
}
public void evictFields(IdentityIF identity, boolean notifyCluster) {
pcache.evictFields(identity, notifyCluster);
}
public void evictField(IdentityIF identity, int field, boolean notifyCluster) {
pcache.evictField(identity, field, notifyCluster);
}
public void clear(boolean notifyCluster) {
pcache.clear(notifyCluster);
}
// -----------------------------------------------------------------------------
// prefetch
// -----------------------------------------------------------------------------
public int prefetch(StorageAccessIF access, Class<?> type, int field, int nextField, boolean traverse, Collection<IdentityIF> identities) {
return pcache.prefetch(access, type, field, nextField, traverse, identities);
}
// -----------------------------------------------------------------------------
// Misc
// -----------------------------------------------------------------------------
protected int percent(int c, int total) {
if (c == 0) return 0;
return Math.round(((100.0f*c)/(1.0f*total)));
}
public void dump() {
System.out.println("StatisticsCache: " + name);
System.out.println(" object hits: " + hits_o + " (" + percent(hits_o, total_o) + "%)");
System.out.println(" object misses: " + misses_o + " (" + percent(misses_o, total_o) + "%)");
System.out.println(" field hits: " + hits_f + " (" + percent(hits_f, total_f) + "%)");
System.out.println(" field misses: " + misses_f + " (" + percent(misses_f, total_f) + "%)");
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("proxy.StatisticsCache@");
sb.append(System.identityHashCode(this));
if (pcache != null)
sb.append(" [parent = ").append(pcache).append(']');
return sb.toString();
}
}