Made subnode check optional in NodeManager.getNode()

Switched from Vector to ArrayList as base class for ExternalizableVector.
Binary representations of both versions of ExternalizableVector should still be
compatible.
This commit is contained in:
hns 2001-07-16 15:30:40 +00:00
parent a974b77f62
commit 58c92aec46
4 changed files with 51 additions and 47 deletions

View file

@ -4,14 +4,14 @@
package helma.objectmodel.db; package helma.objectmodel.db;
import java.io.*; import java.io.*;
import java.util.Vector; import java.util.ArrayList;
/** /**
* A subclass of Vector that implements the Externalizable interface in order * A subclass of Vector that implements the Externalizable interface in order
* to be able to control how it is serialized and deserialized. * to be able to control how it is serialized and deserialized.
*/ */
public class ExternalizableVector extends Vector implements Externalizable { public class ExternalizableVector extends ArrayList implements Externalizable {
static final long serialVersionUID = 2316243615310540423L; static final long serialVersionUID = 2316243615310540423L;
@ -19,7 +19,7 @@ public class ExternalizableVector extends Vector implements Externalizable {
try { try {
int size = in.readInt (); int size = in.readInt ();
for (int i=0; i<size; i++) for (int i=0; i<size; i++)
addElement (in.readObject ()); add (in.readObject ());
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
throw new IOException (x.toString ()); throw new IOException (x.toString ());
} }
@ -29,7 +29,7 @@ public class ExternalizableVector extends Vector implements Externalizable {
int size = size (); int size = size ();
out.writeInt (size); out.writeInt (size);
for (int i=0; i<size; i++) for (int i=0; i<size; i++)
out.writeObject (elementAt (i)); out.writeObject (get (i));
} }
} }

View file

@ -7,7 +7,9 @@ package helma.objectmodel.db;
import java.util.Vector; import java.util.Vector;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.io.*; import java.io.*;
import java.sql.Types; import java.sql.Types;
@ -26,13 +28,13 @@ public class Node implements INode, Serializable {
// The ID of this node's parent node // The ID of this node's parent node
protected String parentID; protected String parentID;
// Ordered list of subnodes of this node // Ordered list of subnodes of this node
private Vector subnodes; private List subnodes;
// Named subnodes (properties) of this node // Named subnodes (properties) of this node
private Hashtable propMap; private Hashtable propMap;
// Other nodes that link to this node. Used for reference counting/checking // Other nodes that link to this node. Used for reference counting/checking
private Vector links; private List links;
// Other nodes that refer to this node as property. Used for reference counting/checking // Other nodes that refer to this node as property. Used for reference counting/checking
private Vector proplinks; private List proplinks;
// the name of the (Hop) prototype - this is stored as standard property instead. // the name of the (Hop) prototype - this is stored as standard property instead.
// private String prototype; // private String prototype;
@ -61,9 +63,9 @@ public class Node implements INode, Serializable {
lastmodified = in.readLong (); lastmodified = in.readLong ();
content = (byte[]) in.readObject (); content = (byte[]) in.readObject ();
contentType = (String) in.readObject (); contentType = (String) in.readObject ();
subnodes = (Vector) in.readObject (); subnodes = (ExternalizableVector) in.readObject ();
links = (Vector) in.readObject (); links = (ExternalizableVector) in.readObject ();
proplinks = (Vector) in.readObject (); proplinks = (ExternalizableVector) in.readObject ();
propMap = (Hashtable) in.readObject (); propMap = (Hashtable) in.readObject ();
anonymous = in.readBoolean (); anonymous = in.readBoolean ();
if (version == 2) if (version == 2)
@ -744,12 +746,12 @@ public class Node implements INode, Serializable {
if (subnodes != null && subnodes.contains (node.getID ())) { if (subnodes != null && subnodes.contains (node.getID ())) {
// Node is already subnode of this - just move to new position // Node is already subnode of this - just move to new position
subnodes.removeElement (node.getID ()); subnodes.remove (node.getID ());
where = Math.min (where, numberOfNodes ()); where = Math.min (where, numberOfNodes ());
subnodes.insertElementAt (node.getID (), where); subnodes.add (where, node.getID ());
} else { } else {
if (subnodes == null) subnodes = new ExternalizableVector (); if (subnodes == null) subnodes = new ExternalizableVector ();
subnodes.insertElementAt (node.getID (), where); subnodes.add (where, node.getID ());
// check if properties are subnodes (_properties.aresubnodes=true) // check if properties are subnodes (_properties.aresubnodes=true)
if (dbmap != null && node.dbmap != null) { if (dbmap != null && node.dbmap != null) {
@ -839,7 +841,7 @@ public class Node implements INode, Serializable {
links = new ExternalizableVector (); links = new ExternalizableVector ();
Object fromID = from.getID (); Object fromID = from.getID ();
if (!links.contains (fromID)) if (!links.contains (fromID))
links.addElement (fromID); links.add (fromID);
} }
public INode getSubnode (String path) { public INode getSubnode (String path) {
@ -900,9 +902,9 @@ public class Node implements INode, Serializable {
if (subnodes.size () > index) { if (subnodes.size () > index) {
// check if there is a group-by relation // check if there is a group-by relation
if (srel != null && srel.groupby != null) if (srel != null && srel.groupby != null)
retval = nmgr.getNode (this, (String) subnodes.elementAt (index), srel); retval = nmgr.getNode (this, (String) subnodes.get (index), srel);
else else
retval = nmgr.getNode ((String) subnodes.elementAt (index), smap); retval = nmgr.getNode ((String) subnodes.get (index), smap);
if (retval != null && retval.parentID == null && !"root".equalsIgnoreCase (retval.getPrototype ())) { if (retval != null && retval.parentID == null && !"root".equalsIgnoreCase (retval.getPrototype ())) {
retval.setParent (this); retval.setParent (this);
retval.anonymous = true; retval.anonymous = true;
@ -944,7 +946,7 @@ public class Node implements INode, Serializable {
node.setSubnodeRelation (snrel); node.setSubnodeRelation (snrel);
} else { } else {
setNode (sid, node); setNode (sid, node);
subnodes.addElement (node.getID ()); subnodes.add (node.getID ());
} }
nmgr.evictKey (node.getKey ()); nmgr.evictKey (node.getKey ());
return node; return node;
@ -982,7 +984,7 @@ public class Node implements INode, Serializable {
} else { } else {
// removed just a link, not the main node. // removed just a link, not the main node.
if (n.links != null) { if (n.links != null) {
n.links.removeElement (this.id); n.links.remove (this.id);
if (n.state == CLEAN) n.markAs (MODIFIED); if (n.state == CLEAN) n.markAs (MODIFIED);
} }
} }
@ -994,7 +996,7 @@ public class Node implements INode, Serializable {
*/ */
protected void releaseNode (Node node) { protected void releaseNode (Node node) {
if (subnodes != null) if (subnodes != null)
subnodes.removeElement (node.getID ()); subnodes.remove (node.getID ());
lastSubnodeChange = System.currentTimeMillis (); lastSubnodeChange = System.currentTimeMillis ();
@ -1044,14 +1046,14 @@ public class Node implements INode, Serializable {
int l = links == null ? 0 : links.size (); int l = links == null ? 0 : links.size ();
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
// TODO: solve dbmap problem // TODO: solve dbmap problem
Node link = nmgr.getNode ((String) links.elementAt (i), null); Node link = nmgr.getNode ((String) links.get (i), null);
if (link != null) link.releaseNode (this); if (link != null) link.releaseNode (this);
} }
// clean up all nodes that use n as a property // clean up all nodes that use n as a property
if (proplinks != null) { if (proplinks != null) {
for (Enumeration e1 = proplinks.elements (); e1.hasMoreElements (); ) try { for (Iterator e1 = proplinks.iterator (); e1.hasNext (); ) try {
String pid = (String) e1.nextElement (); String pid = (String) e1.next ();
Node pnode = nmgr.getNode (pid, null); Node pnode = nmgr.getNode (pid, null);
if (pnode != null) { if (pnode != null) {
nmgr.logEvent("Warning: Can't unset node property of "+pnode.getFullName ()); nmgr.logEvent("Warning: Can't unset node property of "+pnode.getFullName ());
@ -1072,15 +1074,15 @@ public class Node implements INode, Serializable {
// the parent info is not 100% accurate for them. // the parent info is not 100% accurate for them.
if (subnodes != null) { if (subnodes != null) {
Vector v = new Vector (); Vector v = new Vector ();
// removeElement modifies the Vector we are enumerating, so we are extra careful. // remove modifies the Vector we are enumerating, so we are extra careful.
for (Enumeration e3 = getSubnodes (); e3.hasMoreElements(); ) { for (Enumeration e3 = getSubnodes (); e3.hasMoreElements(); ) {
v.addElement (e3.nextElement()); v.add (e3.nextElement());
} }
int m = v.size (); int m = v.size ();
for (int i=0; i<m; i++) { for (int i=0; i<m; i++) {
// getParent() is heuristical/implicit for relational nodes, so we don't base // getParent() is heuristical/implicit for relational nodes, so we don't base
// a cascading delete on that criterium for relational nodes. // a cascading delete on that criterium for relational nodes.
Node n = (Node) v.elementAt (i); Node n = (Node) v.get (i);
if (n.dbmap == null || !n.dbmap.isRelational()) if (n.dbmap == null || !n.dbmap.isRelational())
removeNode (n); removeNode (n);
} }
@ -1616,14 +1618,14 @@ public class Node implements INode, Serializable {
proplinks = new ExternalizableVector (); proplinks = new ExternalizableVector ();
String plid = n.getID (); String plid = n.getID ();
if (!proplinks.contains (plid)) if (!proplinks.contains (plid))
proplinks.addElement (n.getID ()); proplinks.add (n.getID ());
if (state == CLEAN || state == DELETED) if (state == CLEAN || state == DELETED)
markAs (MODIFIED); markAs (MODIFIED);
} }
protected void unregisterPropLink (INode n) { protected void unregisterPropLink (INode n) {
if (proplinks != null) if (proplinks != null)
proplinks.removeElement (n.getID ()); proplinks.remove (n.getID ());
// Server.throwNodeEvent (new NodeEvent (this, NodeEvent.NODE_REMOVED)); // Server.throwNodeEvent (new NodeEvent (this, NodeEvent.NODE_REMOVED));
// Server.throwNodeEvent (new NodeEvent (n, NodeEvent.SUBNODE_REMOVED, this)); // Server.throwNodeEvent (new NodeEvent (n, NodeEvent.SUBNODE_REMOVED, this));
if (state == CLEAN) if (state == CLEAN)
@ -1631,7 +1633,7 @@ public class Node implements INode, Serializable {
} }
public void sanityCheck () { /* public void sanityCheck () {
checkSubnodes (); checkSubnodes ();
checkProperties (); checkProperties ();
checkLinks (); checkLinks ();
@ -1646,10 +1648,10 @@ public class Node implements INode, Serializable {
Vector v = links == null ? null : (Vector) links.clone (); Vector v = links == null ? null : (Vector) links.clone ();
int l = v == null ? 0 : v.size (); int l = v == null ? 0 : v.size ();
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
String k = (String) v.elementAt (i); String k = (String) v.get (i);
Node link = nmgr.getNode (k, null); Node link = nmgr.getNode (k, null);
if (link == null) { if (link == null) {
links.removeElement (k); links.remove (k);
System.out.println ("**** link "+k+": "+this.getFullName ()); System.out.println ("**** link "+k+": "+this.getFullName ());
markAs (MODIFIED); markAs (MODIFIED);
} }
@ -1660,10 +1662,10 @@ public class Node implements INode, Serializable {
Vector v = proplinks == null ? null : (Vector) proplinks.clone (); Vector v = proplinks == null ? null : (Vector) proplinks.clone ();
int l = v == null ? 0 : v.size (); int l = v == null ? 0 : v.size ();
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
String k = (String) v.elementAt (i); String k = (String) v.get (i);
Node link = nmgr.getNode (k, null); Node link = nmgr.getNode (k, null);
if (link == null) { if (link == null) {
proplinks.removeElement (k); proplinks.remove (k);
System.out.println ("**** proplink "+k+": "+this.getFullName ()); System.out.println ("**** proplink "+k+": "+this.getFullName ());
markAs (MODIFIED); markAs (MODIFIED);
} }
@ -1674,10 +1676,10 @@ public class Node implements INode, Serializable {
Vector v = subnodes == null ? null : (Vector) subnodes.clone (); Vector v = subnodes == null ? null : (Vector) subnodes.clone ();
int l = v == null ? 0 : v.size (); int l = v == null ? 0 : v.size ();
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
String k = (String) v.elementAt (i); String k = (String) v.get (i);
Node link = nmgr.getNode (k, null); Node link = nmgr.getNode (k, null);
if (link == null) { if (link == null) {
subnodes.removeElement (k); subnodes.remove (k);
System.out.println ("**** subnode "+k+": "+this.getFullName ()); System.out.println ("**** subnode "+k+": "+this.getFullName ());
markAs (MODIFIED); markAs (MODIFIED);
} }
@ -1697,7 +1699,7 @@ public class Node implements INode, Serializable {
} }
} }
} } */
/** /**
* content-related * content-related

View file

@ -3,14 +3,15 @@
package helma.objectmodel.db; package helma.objectmodel.db;
import java.io.*;
import java.util.Vector;
import java.util.Properties;
import helma.util.CacheMap; import helma.util.CacheMap;
import helma.objectmodel.*; import helma.objectmodel.*;
import helma.framework.core.Application; import helma.framework.core.Application;
import com.sleepycat.db.*; import com.sleepycat.db.*;
import java.sql.*; import java.sql.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector; import java.util.Vector;
import java.util.Enumeration; import java.util.Enumeration;
import com.workingdogs.village.*; import com.workingdogs.village.*;
@ -225,7 +226,7 @@ public final class NodeManager {
if (node instanceof NullNode) { if (node instanceof NullNode) {
if (node.created() < rel.other.lastDataChange) if (node.created() < rel.other.lastDataChange)
node = null; // cached null not valid anymore node = null; // cached null not valid anymore
} else if (home.contains (node) < 0) { } else if (app.doesSubnodeChecking () && home.contains (node) < 0) {
node = null; node = null;
} }
} }
@ -571,7 +572,7 @@ public final class NodeManager {
* Loades subnodes via subnode relation. Only the ID index is loaded, the nodes are * Loades subnodes via subnode relation. Only the ID index is loaded, the nodes are
* loaded later on demand. * loaded later on demand.
*/ */
public Vector getNodeIDs (Node home, Relation rel) throws Exception { public List getNodeIDs (Node home, Relation rel) throws Exception {
Transactor tx = (Transactor) Thread.currentThread (); Transactor tx = (Transactor) Thread.currentThread ();
// tx.timer.beginEvent ("getNodeIDs "+home); // tx.timer.beginEvent ("getNodeIDs "+home);
@ -580,7 +581,7 @@ public final class NodeManager {
// this should never be called for embedded nodes // this should never be called for embedded nodes
throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home); throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home);
} else { } else {
Vector retval = new Vector (); List retval = new ArrayList ();
// if we do a groupby query (creating an intermediate layer of groupby nodes), // if we do a groupby query (creating an intermediate layer of groupby nodes),
// retrieve the value of that field instead of the primary key // retrieve the value of that field instead of the primary key
String idfield = rel.groupby == null ? rel.other.getIDField () : rel.groupby; String idfield = rel.groupby == null ? rel.other.getIDField () : rel.groupby;
@ -617,7 +618,7 @@ public final class NodeManager {
for (int i=0; i<qds.size (); i++) { for (int i=0; i<qds.size (); i++) {
Record rec = qds.getRecord (i); Record rec = qds.getRecord (i);
String kstr = rec.getValue (1).asString (); String kstr = rec.getValue (1).asString ();
retval.addElement (kstr); retval.add (kstr);
// if these are groupby nodes, evict nullNode keys // if these are groupby nodes, evict nullNode keys
if (rel.groupby != null) { if (rel.groupby != null) {
Key key = new Key ((String) null, home.getKey ().getVirtualID (kstr)); Key key = new Key ((String) null, home.getKey ().getVirtualID (kstr));
@ -641,7 +642,7 @@ public final class NodeManager {
* actually loades all nodes in one go, which is better for small node collections. * actually loades all nodes in one go, which is better for small node collections.
* This method is used when xxx.loadmode=aggressive is specified. * This method is used when xxx.loadmode=aggressive is specified.
*/ */
public Vector getNodes (Node home, Relation rel) throws Exception { public List getNodes (Node home, Relation rel) throws Exception {
Transactor tx = (Transactor) Thread.currentThread (); Transactor tx = (Transactor) Thread.currentThread ();
// tx.timer.beginEvent ("getNodes "+home); // tx.timer.beginEvent ("getNodes "+home);
@ -650,7 +651,7 @@ public final class NodeManager {
// this should never be called for embedded nodes // this should never be called for embedded nodes
throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home); throw new RuntimeException ("NodeMgr.countNodes called for non-relational node "+home);
} else { } else {
Vector retval = new Vector (); List retval = new ArrayList ();
DbMapping dbm = rel.other; DbMapping dbm = rel.other;
TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ()); TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
@ -682,7 +683,7 @@ public final class NodeManager {
// create new Nodes. // create new Nodes.
Record rec = tds.getRecord (i); Record rec = tds.getRecord (i);
Node node = new Node (rel.other, rec, safe); Node node = new Node (rel.other, rec, safe);
retval.addElement (node.getID()); retval.add (node.getID());
Key primKey = node.getKey (); Key primKey = node.getKey ();
// do we need to synchronize on primKey here? // do we need to synchronize on primKey here?
synchronized (cache) { synchronized (cache) {

View file

@ -4,6 +4,7 @@
package helma.objectmodel.db; package helma.objectmodel.db;
import helma.objectmodel.*; import helma.objectmodel.*;
import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -47,7 +48,7 @@ import java.util.Vector;
} }
} }
public Vector getNodes (Node home, Relation rel) { public List getNodes (Node home, Relation rel) {
try { try {
return nmgr.getNodes (home, rel); return nmgr.getNodes (home, rel);
} catch (Exception x) { } catch (Exception x) {
@ -57,7 +58,7 @@ import java.util.Vector;
} }
} }
public Vector getNodeIDs (Node home, Relation rel) { public List getNodeIDs (Node home, Relation rel) {
try { try {
return nmgr.getNodeIDs (home, rel); return nmgr.getNodeIDs (home, rel);
} catch (Exception x) { } catch (Exception x) {