new interface method ObjectCache.getStatistics

the statistics of a cache instance for an application can be retrieved
by calling `app.__app__.getCacheStatistics()`. That's not very useful for the 
default `ObjectCache` but essential for looking into what more complex cache
impls like `SwarmCache` do

we could remove all the other cache statistics methods like `getCacheUsage` 
and output that info in the map returned by `getCacheStatistics()`

i had to bump java to 1.5 for the generics.. if that's a problem we can
remove the generics
This commit is contained in:
Simon Oberhammer 2013-04-04 11:24:56 +02:00
parent fd0b77bc11
commit 826987d3a2
5 changed files with 54 additions and 30 deletions

View file

@ -102,8 +102,8 @@
<replace file="${build.work}/src/helma/main/Server.java"
token="__builddate__" value="${TODAY}"/>
<javac srcdir="${build.work}/src"
source="1.4"
target="1.4"
source="1.5"
target="1.5"
destdir="${build.classes}"
debug="${debug}"
deprecation="${deprecation}"

View file

@ -37,7 +37,7 @@ import java.util.ArrayList;
/**
* The central class of a Helma application. This class keeps a pool of
* The central class of a Helma application. This class keeps a pool of
* request evaluators (threads with JavaScript interpreters), waits for
* requests from the Web server or XML-RPC port and dispatches them to
* the evaluators.
@ -227,7 +227,7 @@ public final class Application implements Runnable {
}
this.name = name;
this.caseInsensitive = "true".equalsIgnoreCase(server.getAppsProperties(name).getProperty("caseInsensitive"));
this.repositories = new ArrayList();
@ -456,7 +456,7 @@ public final class Application implements Runnable {
releaseEvaluator(ev);
}
}
// preallocate minThreads request evaluators
int minThreads = 0;
@ -834,6 +834,13 @@ public final class Application implements Runnable {
return nmgr.countCacheEntries();
}
/**
* Returns a map of cache statistics
*/
public Map getCacheStatistics() {
return nmgr.getCacheStatistics();
}
/**
* Set the application's root element to an arbitrary object. After this is called
* with a non-null object, the helma node manager will be bypassed. This function
@ -1389,7 +1396,7 @@ public final class Application implements Runnable {
}
return null;
}
/**
* Returns the correct property name which is either case sensitive or case insensitive
* @param propName the raw property name

View file

@ -110,4 +110,8 @@ public interface ObjectCache {
*/
Object[] getCachedObjects();
/**
* Returns a map of statistics about the cache
*/
java.util.Map<String,Object> getStatistics();
}

View file

@ -56,7 +56,7 @@ public final class NodeManager {
}
/**
* Initialize the NodeManager for the given dbHome and
* Initialize the NodeManager for the given dbHome and
* application properties. An embedded database will be
* created in dbHome if one doesn't already exist.
*/
@ -112,7 +112,7 @@ public final class NodeManager {
}
/**
* Shut down this node manager. This is called when the application
* Shut down this node manager. This is called when the application
* using this node manager is stopped.
*/
public void shutdown() throws DatabaseException {
@ -295,7 +295,7 @@ public final class NodeManager {
synchronized (cache) {
Node old = (Node) cache.put(node.getKey(), node);
if (old != node && old != null && !old.isNullNode() &&
if (old != node && old != null && !old.isNullNode() &&
old.getState() != Node.INVALID) {
cache.put(node.getKey(), old);
cache.put(key, old);
@ -432,14 +432,14 @@ public final class NodeManager {
/**
* Insert a node into a different (relational) database than its default one.
*/
public void exportNode(Node node, DbSource dbs)
public void exportNode(Node node, DbSource dbs)
throws SQLException, ClassNotFoundException {
if (node == null) {
throw new IllegalArgumentException("Node can't be null in exportNode");
}
DbMapping dbm = node.getDbMapping();
if (dbs == null) {
throw new IllegalArgumentException("DbSource can't be null in exportNode");
} else if ((dbm == null) || !dbm.isRelational()) {
@ -448,7 +448,7 @@ public final class NodeManager {
insertRelationalNode(node, dbm, dbs.getConnection());
}
}
/**
* Insert a node into a different (relational) database than its default one.
*/
@ -493,7 +493,7 @@ public final class NodeManager {
for (int i = 0; i < columns.length; i++) {
DbColumn col = columns[i];
if (!col.isMapped())
if (!col.isMapped())
continue;
if (col.isIdField()) {
setStatementValue(stmt, columnNumber, node.getID(), col);
@ -502,7 +502,7 @@ public final class NodeManager {
} else {
Relation rel = col.getRelation();
Property p = rel == null ? null : node.getProperty(rel.getPropName());
if (p != null) {
setStatementValue(stmt, columnNumber, p, col.getType());
} else if (col.isNameField()) {
@ -544,7 +544,7 @@ public final class NodeManager {
app.logError("Error invoking onPersist()", x);
}
}
/**
* Updates a modified node in the embedded db or an external relational database, depending
* on its database mapping.
@ -554,7 +554,7 @@ public final class NodeManager {
*/
public boolean updateNode(IDatabase db, ITransaction txn, Node node)
throws IOException, SQLException, ClassNotFoundException {
invokeOnPersist(node);
DbMapping dbm = node.getDbMapping();
boolean markMappingAsUpdated = false;
@ -1023,7 +1023,7 @@ public final class NodeManager {
return retval;
}
protected List collectMissingKeys(SubnodeList list, int start, int length) {
List retval = null;
for (int i = start; i < start + length; i++) {
@ -1318,7 +1318,7 @@ public final class NodeManager {
DbColumn[] columns = dbm.getColumns();
Relation[] joins = dbm.getJoins();
StringBuffer b = dbm.getSelect(null).append("WHERE ");
dbm.appendCondition(b, idfield, kstr);
dbm.addJoinConstraints(b, " AND ");
@ -1718,21 +1718,28 @@ public final class NodeManager {
}
}
/**
* Add a listener that is notified each time a transaction commits
/**
* Returns a map with statistics about the cache
*/
public Map getCacheStatistics() {
return cache.getStatistics();
}
/**
* Add a listener that is notified each time a transaction commits
* that adds, modifies or deletes any Nodes.
*/
public void addNodeChangeListener(NodeChangeListener listener) {
listeners.add(listener);
}
/**
* Remove a previously added NodeChangeListener.
/**
* Remove a previously added NodeChangeListener.
*/
public void removeNodeChangeListener(NodeChangeListener listener) {
listeners.remove(listener);
}
/**
* Let transactors know if they should collect and fire NodeChangeListener
* events
@ -1740,7 +1747,7 @@ public final class NodeManager {
protected boolean hasNodeChangeListeners() {
return listeners.size() > 0;
}
/**
* Called by transactors after committing.
*/
@ -1757,7 +1764,7 @@ public final class NodeManager {
}
}
}
private void setStatementValue(PreparedStatement stmt, int columnNumber, String value, DbColumn col)
throws SQLException {
if (value == null) {
@ -1780,7 +1787,7 @@ public final class NodeManager {
stmt.setBoolean(stmtNumber, p.getBooleanValue());
break;
case Types.TINYINT:
case Types.BIGINT:
case Types.SMALLINT:
@ -1833,7 +1840,7 @@ public final class NodeManager {
String val = p.getStringValue();
Reader isr = new StringReader (val);
stmt.setCharacterStream (stmtNumber,isr, val.length());
break;
case Types.CHAR:

View file

@ -277,7 +277,7 @@ public class CacheMap implements ObjectCache {
return true;
}
/// Called when the application using this cache is stopped. We
/// Called when the application using this cache is stopped. We
// simply clear out our cache contents.
public synchronized void shutdown() {
clear();
@ -331,6 +331,12 @@ public class CacheMap implements ObjectCache {
return new HashMap(capacity, loadFactor);
}
public Map<String,Object> getStatistics() {
Map<String,Object> stats = new HashMap<String,Object>();
stats.put("size", size());
stats.put("threshold", threshold);
return stats;
}
}