Removed buggy key caching mumbo jumbo
This commit is contained in:
parent
924f3f31a6
commit
683263b9d9
5 changed files with 42 additions and 52 deletions
|
@ -15,8 +15,8 @@ import java.io.Serializable;
|
||||||
*/
|
*/
|
||||||
public class Key {
|
public class Key {
|
||||||
|
|
||||||
protected String type;
|
private String type;
|
||||||
protected String id;
|
private String id;
|
||||||
private int hash;
|
private int hash;
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,15 +45,6 @@ public class Key {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recycle (DbMapping dbmap, String id) {
|
|
||||||
this.type = dbmap == null ? null : dbmap.typename;
|
|
||||||
this.id = id;
|
|
||||||
hash = id.hashCode ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key duplicate () {
|
|
||||||
return new Key (type, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Key for a virtual node contained by this node, that is, a node that does
|
* Get the Key for a virtual node contained by this node, that is, a node that does
|
||||||
|
@ -80,6 +71,10 @@ public class Key {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getID () {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
return type+"["+id+"]";
|
return type+"["+id+"]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,8 @@ public final class NodeManager {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
int cacheSize = Integer.parseInt (props.getProperty ("cachesize", "1000"));
|
int cacheSize = Integer.parseInt (props.getProperty ("cachesize", "1000"));
|
||||||
// Make actual cache size bigger, since we use it only up to the threshold
|
// Make actual cache size bigger, since we use it only up to the threshold
|
||||||
cache = new CacheMap ((int) Math.ceil (cacheSize/0.75f), 0.75f);
|
// cache = new CacheMap ((int) Math.ceil (cacheSize/0.75f), 0.75f);
|
||||||
|
cache = new CacheMap (cacheSize, 0.75f);
|
||||||
IServer.getLogger().log ("set up node cache ("+cacheSize+")");
|
IServer.getLogger().log ("set up node cache ("+cacheSize+")");
|
||||||
|
|
||||||
safe = new WrappedNodeManager (this);
|
safe = new WrappedNodeManager (this);
|
||||||
|
@ -113,9 +114,6 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* private synchronized Node storeNodeInCache (Node n, Key k, Key pk) {
|
|
||||||
|
|
||||||
} */
|
|
||||||
|
|
||||||
public void shutdown () throws DbException {
|
public void shutdown () throws DbException {
|
||||||
db.shutdown ();
|
db.shutdown ();
|
||||||
|
@ -141,8 +139,9 @@ public final class NodeManager {
|
||||||
|
|
||||||
Transactor tx = (Transactor) Thread.currentThread ();
|
Transactor tx = (Transactor) Thread.currentThread ();
|
||||||
// tx.timer.beginEvent ("getNode "+kstr);
|
// tx.timer.beginEvent ("getNode "+kstr);
|
||||||
Key key = tx.key;
|
|
||||||
key.recycle (dbmap, kstr);
|
// it would be a good idea to reuse key objects one day.
|
||||||
|
Key key = new Key (dbmap, kstr);
|
||||||
|
|
||||||
// See if Transactor has already come across this node
|
// See if Transactor has already come across this node
|
||||||
Node node = tx.getVisitedNode (key);
|
Node node = tx.getVisitedNode (key);
|
||||||
|
@ -159,7 +158,6 @@ public final class NodeManager {
|
||||||
// The requested node isn't in the shared cache. Synchronize with key to make sure only one
|
// The requested node isn't in the shared cache. Synchronize with key to make sure only one
|
||||||
// version is fetched from the database.
|
// version is fetched from the database.
|
||||||
node = getNodeByKey (db, tx.txn, kstr, dbmap);
|
node = getNodeByKey (db, tx.txn, kstr, dbmap);
|
||||||
key.recycle (dbmap, kstr);
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
synchronized (cache) {
|
synchronized (cache) {
|
||||||
Node oldnode = (Node) cache.put (node.getKey (), node);
|
Node oldnode = (Node) cache.put (node.getKey (), node);
|
||||||
|
@ -172,7 +170,7 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
tx.visitCleanNode (key.duplicate(), node);
|
tx.visitCleanNode (key, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tx.timer.endEvent ("getNode "+kstr);
|
// tx.timer.endEvent ("getNode "+kstr);
|
||||||
|
@ -188,13 +186,13 @@ public final class NodeManager {
|
||||||
Transactor tx = (Transactor) Thread.currentThread ();
|
Transactor tx = (Transactor) Thread.currentThread ();
|
||||||
// tx.timer.beginEvent ("getNode "+kstr);
|
// tx.timer.beginEvent ("getNode "+kstr);
|
||||||
|
|
||||||
Key key = tx.key;
|
Key key = null;
|
||||||
// If what we want is a virtual node create a "synthetic" key
|
// If what we want is a virtual node create a "synthetic" key
|
||||||
if (rel.virtual || rel.groupby != null)
|
if (rel.virtual || rel.groupby != null)
|
||||||
key.recycle (null, home.getKey ().getVirtualID (kstr));
|
key = new Key ((String) null, home.getKey ().getVirtualID (kstr));
|
||||||
// if a key for a node from within the DB
|
// if a key for a node from within the DB
|
||||||
else
|
else
|
||||||
key.recycle (rel.other, rel.getKeyID (home, kstr));
|
key = new Key (rel.other, rel.getKeyID (home, kstr));
|
||||||
|
|
||||||
// See if Transactor has already come across this node
|
// See if Transactor has already come across this node
|
||||||
Node node = tx.getVisitedNode (key);
|
Node node = tx.getVisitedNode (key);
|
||||||
|
@ -209,7 +207,7 @@ public final class NodeManager {
|
||||||
Node oldnode = (Node) cache.put (node.getKey (), node);
|
Node oldnode = (Node) cache.put (node.getKey (), node);
|
||||||
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
||||||
cache.put (node.getKey (), oldnode);
|
cache.put (node.getKey (), oldnode);
|
||||||
cache.put (key.duplicate(), oldnode);
|
cache.put (key, oldnode);
|
||||||
node = oldnode;
|
node = oldnode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,13 +225,6 @@ public final class NodeManager {
|
||||||
|
|
||||||
node = getNodeByRelation (db, tx.txn, home, kstr, rel);
|
node = getNodeByRelation (db, tx.txn, home, kstr, rel);
|
||||||
|
|
||||||
// HACK: on some occasions (groupby nodes), transactor.key is used recursively
|
|
||||||
// so re-initializing it here is the safest thing to do.
|
|
||||||
if (rel.virtual || rel.groupby != null)
|
|
||||||
key.recycle (null, home.getKey ().getVirtualID (kstr));
|
|
||||||
else
|
|
||||||
key.recycle (rel.other, rel.getKeyID (home, kstr));
|
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
|
||||||
Key primKey = node.getKey ();
|
Key primKey = node.getKey ();
|
||||||
|
@ -244,10 +235,10 @@ public final class NodeManager {
|
||||||
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
||||||
cache.put (primKey, oldnode);
|
cache.put (primKey, oldnode);
|
||||||
if (!keyIsPrimary)
|
if (!keyIsPrimary)
|
||||||
cache.put (key.duplicate(), oldnode);
|
cache.put (key, oldnode);
|
||||||
node = oldnode;
|
node = oldnode;
|
||||||
} else if (!keyIsPrimary) // cache node with secondary key
|
} else if (!keyIsPrimary) // cache node with secondary key
|
||||||
cache.put (key.duplicate(), node);
|
cache.put (key, node);
|
||||||
} // synchronized
|
} // synchronized
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,7 +248,7 @@ public final class NodeManager {
|
||||||
Node oldnode = (Node) cache.put (node.getKey (), node);
|
Node oldnode = (Node) cache.put (node.getKey (), node);
|
||||||
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
if (oldnode != null && oldnode.getState () != Node.INVALID) {
|
||||||
cache.put (node.getKey (), oldnode);
|
cache.put (node.getKey (), oldnode);
|
||||||
cache.put (key.duplicate(), oldnode);
|
cache.put (key, oldnode);
|
||||||
node = oldnode;
|
node = oldnode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,13 +256,14 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
tx.visitCleanNode (key.duplicate(), node);
|
tx.visitCleanNode (key, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tx.timer.endEvent ("getNode "+kstr);
|
// tx.timer.endEvent ("getNode "+kstr);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void registerNode (Node node) {
|
public void registerNode (Node node) {
|
||||||
cache.put (node.getKey (), node);
|
cache.put (node.getKey (), node);
|
||||||
}
|
}
|
||||||
|
@ -923,6 +915,10 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Object[] getCacheEntries () {
|
||||||
|
return cache.getEntryArray ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,6 @@ public class Transactor extends Thread {
|
||||||
private volatile boolean active;
|
private volatile boolean active;
|
||||||
private volatile boolean killed;
|
private volatile boolean killed;
|
||||||
|
|
||||||
// the transactor reuses a key object to avoid unnecessary object creation
|
|
||||||
protected Key key;
|
|
||||||
|
|
||||||
// Transaction for the embedded database
|
// Transaction for the embedded database
|
||||||
protected DbTxn txn;
|
protected DbTxn txn;
|
||||||
// Transactions for SQL data sources
|
// Transactions for SQL data sources
|
||||||
|
@ -52,7 +49,6 @@ public class Transactor extends Thread {
|
||||||
active = false;
|
active = false;
|
||||||
killed = false;
|
killed = false;
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
key = new Key ("", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitNode (Node node) {
|
public void visitNode (Node node) {
|
||||||
|
|
|
@ -130,6 +130,11 @@ import java.util.Vector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object[] getCacheEntries () {
|
||||||
|
return nmgr.getCacheEntries ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,19 +175,6 @@ public class CacheMap {
|
||||||
// @return the old value of the key, or null if it did not have one.
|
// @return the old value of the key, or null if it did not have one.
|
||||||
public synchronized Object put (Object key, Object value) {
|
public synchronized Object put (Object key, Object value) {
|
||||||
|
|
||||||
if (key instanceof helma.objectmodel.Key && value instanceof helma.objectmodel.db.Node) {
|
|
||||||
helma.objectmodel.Key k = (helma.objectmodel.Key) key;
|
|
||||||
helma.objectmodel.db.Node n = (helma.objectmodel.db.Node) value;
|
|
||||||
helma.objectmodel.DbMapping dbm = n.getDbMapping ();
|
|
||||||
String t1 = k.getType ();
|
|
||||||
String t2 = dbm == null ? null: dbm.getTypeName();
|
|
||||||
if (t1 != t2 && (t1 == null || !t1.equals (t2))) {
|
|
||||||
helma.objectmodel.IServer.getLogger().log ("WARNING: "+t1+" != "+t2);
|
|
||||||
System.err.println ("WARNING: "+t1+" != "+t2);
|
|
||||||
Thread.dumpStack ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object oldValue = newTable.put (key, value);
|
Object oldValue = newTable.put (key, value);
|
||||||
if (oldValue != null)
|
if (oldValue != null)
|
||||||
return oldValue;
|
return oldValue;
|
||||||
|
@ -195,8 +182,9 @@ public class CacheMap {
|
||||||
if (oldValue != null)
|
if (oldValue != null)
|
||||||
oldTable.remove( key );
|
oldTable.remove( key );
|
||||||
else {
|
else {
|
||||||
if (size() >= threshold) {
|
if (newTable.size() >= eachCapacity) {
|
||||||
// Rotate the tables.
|
// Rotate the tables.
|
||||||
|
helma.objectmodel.IServer.getLogger().log ("Rotating Cache tables at "+newTable.size()+"/"+oldTable.size()+" (new/old)");
|
||||||
oldTable = newTable;
|
oldTable = newTable;
|
||||||
newTable = new HashMap (eachCapacity, loadFactor);
|
newTable = new HashMap (eachCapacity, loadFactor);
|
||||||
}
|
}
|
||||||
|
@ -222,6 +210,16 @@ public class CacheMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized Object[] getEntryArray () {
|
||||||
|
Object[] k1 = newTable.keySet().toArray();
|
||||||
|
Object[] k2 = oldTable.keySet().toArray();
|
||||||
|
Object[] k = new Object[k1.length+k2.length];
|
||||||
|
System.arraycopy (k1, 0, k, 0, k1.length);
|
||||||
|
System.arraycopy (k2, 0, k, k1.length, k2.length);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue