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:
parent
fd0b77bc11
commit
826987d3a2
5 changed files with 54 additions and 30 deletions
|
@ -102,8 +102,8 @@
|
||||||
<replace file="${build.work}/src/helma/main/Server.java"
|
<replace file="${build.work}/src/helma/main/Server.java"
|
||||||
token="__builddate__" value="${TODAY}"/>
|
token="__builddate__" value="${TODAY}"/>
|
||||||
<javac srcdir="${build.work}/src"
|
<javac srcdir="${build.work}/src"
|
||||||
source="1.4"
|
source="1.5"
|
||||||
target="1.4"
|
target="1.5"
|
||||||
destdir="${build.classes}"
|
destdir="${build.classes}"
|
||||||
debug="${debug}"
|
debug="${debug}"
|
||||||
deprecation="${deprecation}"
|
deprecation="${deprecation}"
|
||||||
|
|
|
@ -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
|
* request evaluators (threads with JavaScript interpreters), waits for
|
||||||
* requests from the Web server or XML-RPC port and dispatches them to
|
* requests from the Web server or XML-RPC port and dispatches them to
|
||||||
* the evaluators.
|
* the evaluators.
|
||||||
|
@ -227,7 +227,7 @@ public final class Application implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.caseInsensitive = "true".equalsIgnoreCase(server.getAppsProperties(name).getProperty("caseInsensitive"));
|
this.caseInsensitive = "true".equalsIgnoreCase(server.getAppsProperties(name).getProperty("caseInsensitive"));
|
||||||
|
|
||||||
this.repositories = new ArrayList();
|
this.repositories = new ArrayList();
|
||||||
|
@ -456,7 +456,7 @@ public final class Application implements Runnable {
|
||||||
releaseEvaluator(ev);
|
releaseEvaluator(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// preallocate minThreads request evaluators
|
// preallocate minThreads request evaluators
|
||||||
int minThreads = 0;
|
int minThreads = 0;
|
||||||
|
|
||||||
|
@ -834,6 +834,13 @@ public final class Application implements Runnable {
|
||||||
return nmgr.countCacheEntries();
|
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
|
* 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
|
* 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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the correct property name which is either case sensitive or case insensitive
|
* Returns the correct property name which is either case sensitive or case insensitive
|
||||||
* @param propName the raw property name
|
* @param propName the raw property name
|
||||||
|
|
|
@ -110,4 +110,8 @@ public interface ObjectCache {
|
||||||
*/
|
*/
|
||||||
Object[] getCachedObjects();
|
Object[] getCachedObjects();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of statistics about the cache
|
||||||
|
*/
|
||||||
|
java.util.Map<String,Object> getStatistics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* application properties. An embedded database will be
|
||||||
* created in dbHome if one doesn't already exist.
|
* 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.
|
* using this node manager is stopped.
|
||||||
*/
|
*/
|
||||||
public void shutdown() throws DatabaseException {
|
public void shutdown() throws DatabaseException {
|
||||||
|
@ -295,7 +295,7 @@ public final class NodeManager {
|
||||||
synchronized (cache) {
|
synchronized (cache) {
|
||||||
Node old = (Node) cache.put(node.getKey(), node);
|
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) {
|
old.getState() != Node.INVALID) {
|
||||||
cache.put(node.getKey(), old);
|
cache.put(node.getKey(), old);
|
||||||
cache.put(key, 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.
|
* 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 {
|
throws SQLException, ClassNotFoundException {
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw new IllegalArgumentException("Node can't be null in exportNode");
|
throw new IllegalArgumentException("Node can't be null in exportNode");
|
||||||
}
|
}
|
||||||
|
|
||||||
DbMapping dbm = node.getDbMapping();
|
DbMapping dbm = node.getDbMapping();
|
||||||
|
|
||||||
if (dbs == null) {
|
if (dbs == null) {
|
||||||
throw new IllegalArgumentException("DbSource can't be null in exportNode");
|
throw new IllegalArgumentException("DbSource can't be null in exportNode");
|
||||||
} else if ((dbm == null) || !dbm.isRelational()) {
|
} else if ((dbm == null) || !dbm.isRelational()) {
|
||||||
|
@ -448,7 +448,7 @@ public final class NodeManager {
|
||||||
insertRelationalNode(node, dbm, dbs.getConnection());
|
insertRelationalNode(node, dbm, dbs.getConnection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a node into a different (relational) database than its default one.
|
* 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++) {
|
for (int i = 0; i < columns.length; i++) {
|
||||||
DbColumn col = columns[i];
|
DbColumn col = columns[i];
|
||||||
if (!col.isMapped())
|
if (!col.isMapped())
|
||||||
continue;
|
continue;
|
||||||
if (col.isIdField()) {
|
if (col.isIdField()) {
|
||||||
setStatementValue(stmt, columnNumber, node.getID(), col);
|
setStatementValue(stmt, columnNumber, node.getID(), col);
|
||||||
|
@ -502,7 +502,7 @@ public final class NodeManager {
|
||||||
} else {
|
} else {
|
||||||
Relation rel = col.getRelation();
|
Relation rel = col.getRelation();
|
||||||
Property p = rel == null ? null : node.getProperty(rel.getPropName());
|
Property p = rel == null ? null : node.getProperty(rel.getPropName());
|
||||||
|
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
setStatementValue(stmt, columnNumber, p, col.getType());
|
setStatementValue(stmt, columnNumber, p, col.getType());
|
||||||
} else if (col.isNameField()) {
|
} else if (col.isNameField()) {
|
||||||
|
@ -544,7 +544,7 @@ public final class NodeManager {
|
||||||
app.logError("Error invoking onPersist()", x);
|
app.logError("Error invoking onPersist()", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a modified node in the embedded db or an external relational database, depending
|
* Updates a modified node in the embedded db or an external relational database, depending
|
||||||
* on its database mapping.
|
* on its database mapping.
|
||||||
|
@ -554,7 +554,7 @@ public final class NodeManager {
|
||||||
*/
|
*/
|
||||||
public boolean updateNode(IDatabase db, ITransaction txn, Node node)
|
public boolean updateNode(IDatabase db, ITransaction txn, Node node)
|
||||||
throws IOException, SQLException, ClassNotFoundException {
|
throws IOException, SQLException, ClassNotFoundException {
|
||||||
|
|
||||||
invokeOnPersist(node);
|
invokeOnPersist(node);
|
||||||
DbMapping dbm = node.getDbMapping();
|
DbMapping dbm = node.getDbMapping();
|
||||||
boolean markMappingAsUpdated = false;
|
boolean markMappingAsUpdated = false;
|
||||||
|
@ -1023,7 +1023,7 @@ public final class NodeManager {
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List collectMissingKeys(SubnodeList list, int start, int length) {
|
protected List collectMissingKeys(SubnodeList list, int start, int length) {
|
||||||
List retval = null;
|
List retval = null;
|
||||||
for (int i = start; i < start + length; i++) {
|
for (int i = start; i < start + length; i++) {
|
||||||
|
@ -1318,7 +1318,7 @@ public final class NodeManager {
|
||||||
|
|
||||||
DbColumn[] columns = dbm.getColumns();
|
DbColumn[] columns = dbm.getColumns();
|
||||||
Relation[] joins = dbm.getJoins();
|
Relation[] joins = dbm.getJoins();
|
||||||
|
|
||||||
StringBuffer b = dbm.getSelect(null).append("WHERE ");
|
StringBuffer b = dbm.getSelect(null).append("WHERE ");
|
||||||
dbm.appendCondition(b, idfield, kstr);
|
dbm.appendCondition(b, idfield, kstr);
|
||||||
dbm.addJoinConstraints(b, " AND ");
|
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.
|
* that adds, modifies or deletes any Nodes.
|
||||||
*/
|
*/
|
||||||
public void addNodeChangeListener(NodeChangeListener listener) {
|
public void addNodeChangeListener(NodeChangeListener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a previously added NodeChangeListener.
|
* Remove a previously added NodeChangeListener.
|
||||||
*/
|
*/
|
||||||
public void removeNodeChangeListener(NodeChangeListener listener) {
|
public void removeNodeChangeListener(NodeChangeListener listener) {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Let transactors know if they should collect and fire NodeChangeListener
|
* Let transactors know if they should collect and fire NodeChangeListener
|
||||||
* events
|
* events
|
||||||
|
@ -1740,7 +1747,7 @@ public final class NodeManager {
|
||||||
protected boolean hasNodeChangeListeners() {
|
protected boolean hasNodeChangeListeners() {
|
||||||
return listeners.size() > 0;
|
return listeners.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by transactors after committing.
|
* Called by transactors after committing.
|
||||||
*/
|
*/
|
||||||
|
@ -1757,7 +1764,7 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setStatementValue(PreparedStatement stmt, int columnNumber, String value, DbColumn col)
|
private void setStatementValue(PreparedStatement stmt, int columnNumber, String value, DbColumn col)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -1780,7 +1787,7 @@ public final class NodeManager {
|
||||||
stmt.setBoolean(stmtNumber, p.getBooleanValue());
|
stmt.setBoolean(stmtNumber, p.getBooleanValue());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Types.TINYINT:
|
case Types.TINYINT:
|
||||||
case Types.BIGINT:
|
case Types.BIGINT:
|
||||||
case Types.SMALLINT:
|
case Types.SMALLINT:
|
||||||
|
@ -1833,7 +1840,7 @@ public final class NodeManager {
|
||||||
String val = p.getStringValue();
|
String val = p.getStringValue();
|
||||||
Reader isr = new StringReader (val);
|
Reader isr = new StringReader (val);
|
||||||
stmt.setCharacterStream (stmtNumber,isr, val.length());
|
stmt.setCharacterStream (stmtNumber,isr, val.length());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Types.CHAR:
|
case Types.CHAR:
|
||||||
|
|
|
@ -277,7 +277,7 @@ public class CacheMap implements ObjectCache {
|
||||||
return true;
|
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.
|
// simply clear out our cache contents.
|
||||||
public synchronized void shutdown() {
|
public synchronized void shutdown() {
|
||||||
clear();
|
clear();
|
||||||
|
@ -331,6 +331,12 @@ public class CacheMap implements ObjectCache {
|
||||||
return new HashMap(capacity, loadFactor);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue