Removed buggy key caching mumbo jumbo

This commit is contained in:
hns 2001-02-24 05:24:15 +00:00
parent 924f3f31a6
commit 683263b9d9
5 changed files with 42 additions and 52 deletions

View file

@ -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+"]";
} }

View file

@ -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 ();
}
} }

View file

@ -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) {

View file

@ -130,6 +130,11 @@ import java.util.Vector;
} }
} }
public Object[] getCacheEntries () {
return nmgr.getCacheEntries ();
}
} }

View file

@ -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;
}
} }