You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2007/09/20 20:39:09 UTC
svn commit: r577864 - in /jackrabbit/branches/1.3:
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java
jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java
Author: jukka
Date: Thu Sep 20 11:39:09 2007
New Revision: 577864
URL: http://svn.apache.org/viewvc?rev=577864&view=rev
Log:
1.3: Merged revision 570736 (JCR-1082)
Modified:
jackrabbit/branches/1.3/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java
jackrabbit/branches/1.3/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java
Modified: jackrabbit/branches/1.3/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.3/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java?rev=577864&r1=577863&r2=577864&view=diff
==============================================================================
--- jackrabbit/branches/1.3/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java (original)
+++ jackrabbit/branches/1.3/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java Thu Sep 20 11:39:09 2007
@@ -375,35 +375,47 @@
/**
* {@inheritDoc}
* <p/>
- * Generate subsequent add and remove notifications for every replacement. This method
- * currently assumes that the reordering is detectable by comparing the state's child
- * node entries to the overlayed state's child node entries. It is not able to handle
- * a transient reordering and will therefore evict its cached entry if such a situation
- * is detected.
+ * Iterate over all cached children of this state and verify each
+ * child's position.
*/
public void nodesReplaced(NodeState state) {
- List entries = state.getReorderedChildNodeEntries();
- if (entries.size() == 0) {
- synchronized (cacheMonitor) {
- if (idCache.containsKey(state.getNodeId())) {
- evict(state.getNodeId());
+ synchronized (cacheMonitor) {
+ LRUEntry entry = (LRUEntry) idCache.get(state.getNodeId());
+ if (entry != null) {
+ PathMap.Element element = entry.getElement();
+ Iterator iter = element.getChildren();
+ while (iter.hasNext()) {
+ PathMap.Element child = (PathMap.Element) iter.next();
+ LRUEntry childEntry = (LRUEntry) child.get();
+ if (childEntry == null) {
+ /**
+ * Child has no associated UUID information: we're
+ * therefore unable to determine if this child's
+ * position is still accurate and have to assume
+ * the worst and remove it.
+ */
+ child.remove(false);
+ remove(child);
+ continue;
+ }
+ NodeId childId = childEntry.getId();
+ NodeState.ChildNodeEntry cne = state.getChildNodeEntry(childId);
+ if (cne == null) {
+ /* Child no longer in parent node state, so remove it */
+ child.remove(false);
+ remove(child);
+ continue;
+ }
+ if (!cne.getName().equals(child.getName()) ||
+ cne.getIndex() != child.getNormalizedIndex()) {
+ /* Child still exists but at a different position */
+ element.move(child.getPathElement(),
+ Path.PathElement.create(cne.getName(), cne.getIndex()));
+ continue;
+ }
+ /* At this point the child's position is still valid */
}
}
- return;
- }
- Iterator iter = entries.iterator();
- while (iter.hasNext()) {
- NodeState.ChildNodeEntry now = (NodeState.ChildNodeEntry) iter.next();
- NodeState.ChildNodeEntry old =
- ((NodeState) state.getOverlayedState()).getChildNodeEntry(now.getId());
-
- if (old == null) {
- log.warn("Reordered child node not found in old list.");
- continue;
- }
-
- nodeAdded(state, now.getName(), now.getIndex(), now.getId());
- nodeRemoved(state, old.getName(), old.getIndex(), old.getId());
}
}
@@ -486,23 +498,6 @@
synchronized (cacheMonitor) {
if (idCache.get(id) != null) {
return;
- }
-
- /**
- * Do not cache paths to elements if the parent is transient, since
- * children may be reordered multiple times (see JCR-993). If a
- * child's position is cached at some intermediate stage but the
- * total reordering effectively leaves the child at its initial
- * position, the child's bad position is hardly detectable.
- */
- try {
- NodeId parentId = state.getParentId();
- if (parentId != null && provider.getItemState(parentId).isTransient()) {
- return;
- }
- } catch (ItemStateException e) {
- String msg = "Unable to retrieve parent state of: " + id;
- log.warn(msg, e);
}
if (idCache.size() >= upperLimit) {
Modified: jackrabbit/branches/1.3/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.3/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java?rev=577864&r1=577863&r2=577864&view=diff
==============================================================================
--- jackrabbit/branches/1.3/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java (original)
+++ jackrabbit/branches/1.3/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/PathMap.java Thu Sep 20 11:39:09 2007
@@ -264,22 +264,28 @@
* @return removed child, may be <code>null</code>
*/
public Element remove(Path.PathElement nameIndex) {
- return remove(nameIndex, true);
+ return remove(nameIndex, true, true);
}
/**
* Remove a child. If <code>shift</code> is set to <code>true</code>,
* will shift all children having an index greater than the child
- * removed to the left. If there are no more children left in
+ * removed to the left. If <code>removeIfEmpty</code> is set to
+ * <code>true</code> and there are no more children left in
* this element and no object is associated with this element, the
* element itself gets removed.
*
* @param nameIndex child's path element
* @param shift whether to shift same name siblings having a greater
* index to the left
+ * @param removeIfEmpty remove this element itself if it contains
+ * no more children and is not associated to
+ * an element
* @return removed child, may be <code>null</code>
*/
- private Element remove(Path.PathElement nameIndex, boolean shift) {
+ private Element remove(Path.PathElement nameIndex, boolean shift,
+ boolean removeIfEmpty) {
+
// convert 1-based index value to 0-base value
int index = getZeroBasedIndex(nameIndex);
if (children == null) {
@@ -303,8 +309,8 @@
element.parent = null;
childrenCount--;
}
- if (childrenCount == 0 && obj == null && parent != null) {
- parent.remove(getPathElement(), shift);
+ if (removeIfEmpty && childrenCount == 0 && obj == null && parent != null) {
+ parent.remove(getPathElement(), shift, true);
}
return element;
}
@@ -323,7 +329,7 @@
*/
public void remove(boolean shift) {
if (parent != null) {
- parent.remove(getPathElement(), shift);
+ parent.remove(getPathElement(), shift, true);
} else {
// Removing the root node is not possible: if it has become
// invalid, remove all its children and the associated object
@@ -342,8 +348,28 @@
childrenCount = 0;
if (obj == null && parent != null) {
- parent.remove(getPathElement(), false);
+ parent.remove(getPathElement(), false, true);
+ }
+ }
+
+ /**
+ * Move a child of this element to a different location inside the
+ * same parent.
+ *
+ * @param oldNameIndex old name/index
+ * @param newNameIndex new name/index
+ * @return <code>true</code> if the element was successfully moved;
+ * otherwise <code>false</code>
+ */
+ public boolean move(Path.PathElement oldNameIndex,
+ Path.PathElement newNameIndex) {
+
+ Element child = remove(oldNameIndex, false, false);
+ if (child != null) {
+ put(newNameIndex, child);
+ return true;
}
+ return false;
}
/**
@@ -362,7 +388,7 @@
this.obj = obj;
if (obj == null && childrenCount == 0 && parent != null) {
- parent.remove(getPathElement(), false);
+ parent.remove(getPathElement(), false, true);
}
}