fixed bug with null node caching and groupby nodes.

This commit is contained in:
hns 2001-03-23 17:49:09 +00:00
parent df78802f57
commit c2a80bb151
3 changed files with 31 additions and 7 deletions

View file

@ -329,6 +329,7 @@ public class Node implements INode, Serializable {
if (state == TRANSIENT)
return; // no need to lock transient node
Transactor current = (Transactor) Thread.currentThread ();
if (!current.isActive ())
throw new helma.framework.TimeoutException ();
if (state == INVALID) {
@ -336,10 +337,12 @@ public class Node implements INode, Serializable {
Thread.dumpStack ();
throw new ConcurrencyException ("Node "+this+" was invalidated by another thread.");
}
if (lock != null && lock != current && lock.isAlive () && lock.isActive ()) {
nmgr.logEvent ("Concurrency conflict for "+this+", lock held by "+lock);
throw new ConcurrencyException ("Tried to modify "+this+" from two threads at the same time.");
}
current.visitNode (this);
lock = current;
}
@ -602,12 +605,15 @@ public class Node implements INode, Serializable {
}
/**
* Get parent, retrieving it if necessary.
*/
public INode getParent () {
// check what's specified in the type.properties for this node.
ParentInfo[] parentInfo = null;
if (dbmap != null && dbmap.isRelational () &&
(lastParentSet < dbmap.getLastTypeChange() || lastParentSet < lastmodified))
(lastParentSet < dbmap.getLastTypeChange() || lastParentSet < lastmodified))
parentInfo = dbmap.getParentInfo ();
// check if current parent candidate matches presciption, if not, try to get it
@ -646,6 +652,16 @@ public class Node implements INode, Serializable {
}
/**
* Get parent, using cached info if it exists.
*/
public Node getCachedParent () {
if (parentID == null)
return null;
return nmgr.getNode (parentID, parentmap);
}
/**
* INode-related
*/
@ -948,6 +964,7 @@ public class Node implements INode, Serializable {
// need to query parent before releaseNode is called, since this may change the parent
// to the next option described in the type.properties _parent info
INode parent = n.getParent ();
releaseNode (n);
if (parent == this) {

View file

@ -165,7 +165,7 @@ public final class NodeManager {
if (node != null) {
synchronized (cache) {
Node oldnode = (Node) cache.put (node.getKey (), node);
if (oldnode != null && oldnode.getState () != Node.INVALID) {
if (oldnode != null && oldnode.getState () != Node.INVALID && oldnode != nullNode) {
cache.put (node.getKey (), oldnode);
node = oldnode;
}
@ -254,6 +254,7 @@ public final class NodeManager {
}
}
} else if (node == nullNode) {
// the nullNode caches a null value, i.e. an object that doesn't exist
return null;
} else {
// update primary key in cache to keep it from being flushed, see above
@ -454,7 +455,7 @@ public final class NodeManager {
}
// update may cause changes in the node's parent subnode array
if (node.isAnonymous()) {
Node parent = (Node) node.getParent ();
Node parent = node.getCachedParent ();
if (parent != null)
parent.lastSubnodeChange = System.currentTimeMillis ();
}
@ -591,7 +592,14 @@ public final class NodeManager {
qds.fetchRecords ();
for (int i=0; i<qds.size (); i++) {
Record rec = qds.getRecord (i);
retval.addElement (rec.getValue (1).asString ());
String kstr = rec.getValue (1).asString ();
retval.addElement (kstr);
// if these are groupby nodes, evict nullNode keys
if (rel.groupby != null) {
Key key = new Key ((String) null, home.getKey ().getVirtualID (kstr));
if (cache.get (key) == nullNode)
evictKey (key);
}
}
} finally {

View file

@ -129,7 +129,6 @@ public class Transactor extends Thread {
for (Iterator i=nodes.values().iterator(); i.hasNext (); ) {
Node node = (Node) i.next ();
// update nodes in db
int nstate = node.getState ();
if (nstate == Node.NEW) {
@ -137,12 +136,12 @@ public class Transactor extends Thread {
nmgr.insertNode (nmgr.db, txn, node);
node.setState (Node.CLEAN);
ins++;
nmgr.app.logEvent ("inserted: Node "+node.getName ()+"/"+node.getID ());
nmgr.app.logEvent ("inserted: Node "+node.getPrototype ()+"/"+node.getID ());
} else if (nstate == Node.MODIFIED) {
nmgr.updateNode (nmgr.db, txn, node);
node.setState (Node.CLEAN);
upd++;
nmgr.app.logEvent ("updated: Node "+node.getName ()+"/"+node.getID ());
nmgr.app.logEvent ("updated: Node "+node.getPrototype ()+"/"+node.getID ());
} else if (nstate == Node.DELETED) {
// nmgr.app.logEvent ("deleted: "+node.getFullName ()+" ("+node.getName ()+")");
nmgr.deleteNode (nmgr.db, txn, node);