You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2006/02/17 18:20:04 UTC
svn commit: r378574 -
/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
Author: mreutegg
Date: Fri Feb 17 09:20:00 2006
New Revision: 378574
URL: http://svn.apache.org/viewcvs?rev=378574&view=rev
Log:
- use copy-on-write in NodeState for: child node entries, mixin type names and property names.
Modified:
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java?rev=378574&r1=378573&r2=378574&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java Fri Feb 17 09:20:00 2006
@@ -60,7 +60,7 @@
/**
* the names of this node's mixin types
*/
- private HashSet mixinTypeNames = new HashSet();
+ private Set mixinTypeNames = Collections.EMPTY_SET;
/**
* the id of this node state.
@@ -83,11 +83,23 @@
private ChildNodeEntries childNodeEntries = new ChildNodeEntries();
/**
+ * Set to <code>true</code> if {@link #childNodeEntries} are shared between
+ * different <code>NodeState</code> instance.
+ */
+ private boolean sharedChildNodeEntries = false;
+
+ /**
* set of property names (QName objects)
*/
private HashSet propertyNames = new HashSet();
/**
+ * Set to <code>true</code> if {@link #propertyNames} is shared between
+ * different <code>NodeState</code> instances.
+ */
+ private boolean sharedPropertyNames = false;
+
+ /**
* Listeners (weak references)
*/
private final transient Collection listeners = new WeakIdentityCollection(3);
@@ -132,10 +144,12 @@
id = nodeState.id;
parentId = nodeState.parentId;
nodeTypeName = nodeState.nodeTypeName;
- mixinTypeNames = (HashSet) nodeState.mixinTypeNames.clone();
+ mixinTypeNames = nodeState.mixinTypeNames;
defId = nodeState.defId;
- propertyNames = (HashSet) nodeState.propertyNames.clone();
- childNodeEntries = (ChildNodeEntries) nodeState.childNodeEntries.clone();
+ propertyNames = nodeState.propertyNames;
+ sharedPropertyNames = nodeState.sharedPropertyNames = true;
+ childNodeEntries = nodeState.childNodeEntries;
+ sharedChildNodeEntries = nodeState.sharedChildNodeEntries = true;
}
}
@@ -208,8 +222,11 @@
* @param names set of names of mixin types
*/
public synchronized void setMixinTypeNames(Set names) {
- mixinTypeNames.clear();
- mixinTypeNames.addAll(names);
+ if (names instanceof HashSet) {
+ mixinTypeNames = (Set) ((HashSet) names).clone();
+ } else {
+ mixinTypeNames = new HashSet(names);
+ }
}
/**
@@ -349,6 +366,10 @@
*/
public synchronized ChildNodeEntry addChildNodeEntry(QName nodeName,
NodeId id) {
+ if (sharedChildNodeEntries) {
+ childNodeEntries = (ChildNodeEntries) childNodeEntries.clone();
+ sharedChildNodeEntries = false;
+ }
ChildNodeEntry entry = childNodeEntries.add(nodeName, id);
notifyNodeAdded(entry);
return entry;
@@ -365,6 +386,10 @@
*/
public synchronized boolean renameChildNodeEntry(QName oldName, int index,
QName newName) {
+ if (sharedChildNodeEntries) {
+ childNodeEntries = (ChildNodeEntries) childNodeEntries.clone();
+ sharedChildNodeEntries = false;
+ }
ChildNodeEntry oldEntry = childNodeEntries.remove(oldName, index);
if (oldEntry != null) {
ChildNodeEntry newEntry =
@@ -385,6 +410,10 @@
* in the list of child node entries and could be removed.
*/
public synchronized boolean removeChildNodeEntry(QName nodeName, int index) {
+ if (sharedChildNodeEntries) {
+ childNodeEntries = (ChildNodeEntries) childNodeEntries.clone();
+ sharedChildNodeEntries = false;
+ }
ChildNodeEntry entry = childNodeEntries.remove(nodeName, index);
if (entry != null) {
notifyNodeRemoved(entry);
@@ -400,6 +429,10 @@
* in the list of child node entries and could be removed.
*/
public synchronized boolean removeChildNodeEntry(NodeId id) {
+ if (sharedChildNodeEntries) {
+ childNodeEntries = (ChildNodeEntries) childNodeEntries.clone();
+ sharedChildNodeEntries = false;
+ }
ChildNodeEntry entry = childNodeEntries.remove(id);
if (entry != null) {
notifyNodeRemoved(entry);
@@ -411,6 +444,10 @@
* Removes all <code>ChildNodeEntry</code>s.
*/
public synchronized void removeAllChildNodeEntries() {
+ if (sharedChildNodeEntries) {
+ childNodeEntries = (ChildNodeEntries) childNodeEntries.clone();
+ sharedChildNodeEntries = false;
+ }
childNodeEntries.removeAll();
}
@@ -423,9 +460,16 @@
// optimization
ChildNodeEntries entries = (ChildNodeEntries) nodeEntries;
childNodeEntries = (ChildNodeEntries) entries.clone();
+ sharedChildNodeEntries = false;
} else {
- childNodeEntries.removeAll();
+ if (sharedChildNodeEntries) {
+ childNodeEntries = new ChildNodeEntries();
+ sharedChildNodeEntries = false;
+ } else {
+ childNodeEntries.removeAll();
+ }
childNodeEntries.addAll(nodeEntries);
+
}
notifyNodesReplaced();
}
@@ -448,6 +492,10 @@
* @param propName <code>QName</code> object specifying the property name
*/
public synchronized void addPropertyName(QName propName) {
+ if (sharedPropertyNames) {
+ propertyNames = (HashSet) propertyNames.clone();
+ sharedPropertyNames = false;
+ }
propertyNames.add(propName);
}
@@ -459,6 +507,10 @@
* in the list of property name entries and could be removed.
*/
public synchronized boolean removePropertyName(QName propName) {
+ if (sharedPropertyNames) {
+ propertyNames = (HashSet) propertyNames.clone();
+ sharedPropertyNames = false;
+ }
return propertyNames.remove(propName);
}
@@ -466,7 +518,12 @@
* Removes all property name entries.
*/
public synchronized void removeAllPropertyNames() {
- propertyNames.clear();
+ if (sharedPropertyNames) {
+ propertyNames = new HashSet();
+ sharedPropertyNames = false;
+ } else {
+ propertyNames.clear();
+ }
}
/**
@@ -476,10 +533,17 @@
public synchronized void setPropertyNames(Set propNames) {
if (propNames instanceof HashSet) {
HashSet names = (HashSet) propNames;
- propNames = (HashSet) names.clone();
+ propertyNames = (HashSet) names.clone();
+ sharedPropertyNames = false;
+ } else {
+ if (sharedPropertyNames) {
+ propertyNames = new HashSet();
+ sharedPropertyNames = false;
+ } else {
+ propertyNames.clear();
+ }
+ propertyNames.addAll(propNames);
}
- propertyNames.clear();
- propertyNames.addAll(propNames);
}
/**
Re: svn commit: r378574 - /incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
Posted by Marcel Reutegger <ma...@gmx.net>.
just wanted to give some more details on the NodeState change I did last
friday. Even though the actual code change is only minor, the underlying
concept changed somewhat more significant.
Instead of cloning state information in NodeState on read, child node
entries, mixin type names and property names are now cloned on write.
Mixin type names are copied on each write, as I think those change only
rarely and the size of the collection is rather small.
Property names and in particular child node entries now have an
additional flag that indicates if the collection is shared. The shared
flag is set if the collection (prop names or child node entries) is
shallow-copied in NodeState.copy(). From that point on the collection
must not be changed anymore. If a NodeState modifies e.g. child node
entries, it first has to check if it is shared and in effect read-only.
If it is shared the NodeState then clones the read-only child node
entries, modifies the resulting child node entries and resets the shared
flag.
With this change the usage of ChildNodeEntries.clone() drops significantly.
# of clone() calls while running o.a.j.test.api.TestAll:
Before: ~84'000
After: ~4'100
regards
marcel
mreutegg@apache.org wrote:
> Author: mreutegg
> Date: Fri Feb 17 09:20:00 2006
> New Revision: 378574
>
> URL: http://svn.apache.org/viewcvs?rev=378574&view=rev
> Log:
> - use copy-on-write in NodeState for: child node entries, mixin type names and property names.
>
> Modified:
> incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
>
> Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
> URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/NodeState.java?rev=378574&r1=378573&r2=378574&view=diff