Author: mreutegg Date: Thu Jun 8 03:00:21 2006 New Revision: 412712 URL: http://svn.apache.org/viewvc?rev=412712&view=rev Log: JCR-454: Query with document order fails when result set size > caching hierarchy manager size Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PathMap.java Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java?rev=412712&r1=412711&r2=412712&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java (original) +++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java Thu Jun 8 03:00:21 2006 @@ -305,7 +305,7 @@ if (cne == null) { // Item does not exist, remove child.remove(); - evict(child); + remove(child); return; } @@ -313,7 +313,7 @@ if (childEntry != null && !cne.getId().equals(childEntry.getId())) { // Different child item, remove child.remove(); - evict(child); + remove(child); } } } @@ -324,7 +324,7 @@ */ public void stateDestroyed(ItemState destroyed) { destroyed.removeListener(this); - evict(destroyed.getId()); + remove(destroyed.getId()); } /** @@ -332,7 +332,14 @@ */ public void stateDiscarded(ItemState discarded) { discarded.removeListener(this); - evict(discarded.getId()); + if (discarded.isTransient() && !discarded.hasOverlayedState()) { + // a new node has been discarded -> remove from cache + remove(discarded.getId()); + } else if (provider.hasItemState(discarded.getId())) { + evict(discarded.getId()); + } else { + remove(discarded.getId()); + } } /** @@ -491,6 +498,11 @@ } PathMap.Element element = pathCache.put(path); + if (element.get() != null) { + if (!id.equals(((LRUEntry) element.get()).getId())) { + log.warn("overwriting PathMap.Element"); + } + } LRUEntry entry = new LRUEntry(id, element); element.set(entry); idCache.put(id, entry); @@ -531,30 +543,32 @@ } /** - * Evict item from cache. Evicts the associated LRUEntry + * Remove item from cache. Removes the associated LRUEntry + * and the PathMap.Element with it. Indexes of same name + * sibling elements are shifted! * * @param id item id */ - private void evict(ItemId id) { + private void remove(ItemId id) { synchronized (cacheMonitor) { LRUEntry entry = (LRUEntry) idCache.get(id); if (entry != null) { - evict(entry, true); + remove(entry, true); } } } /** - * Evict item from cache + * Remove item from cache. Index of same name sibling items are shifted! * * @param entry LRU entry * @param removeFromPathCache whether to remove from path cache */ - private void evict(LRUEntry entry, boolean removeFromPathCache) { + private void remove(LRUEntry entry, boolean removeFromPathCache) { synchronized (cacheMonitor) { if (removeFromPathCache) { PathMap.Element element = entry.getElement(); - evict(element); + remove(element); element.remove(); } else { idCache.remove(entry.getId()); @@ -564,16 +578,57 @@ } /** - * Evict path map element from cache. This will traverse all children - * of this element and evict the objects associated with them + * Evict item from cache. Index of same name sibling items are not + * shifted! + * + * @param entry LRU entry + * @param removeFromPathCache whether to remove from path cache + */ + private void evict(LRUEntry entry, boolean removeFromPathCache) { + synchronized (cacheMonitor) { + if (removeFromPathCache) { + PathMap.Element element = entry.getElement(); + element.traverse(new PathMap.ElementVisitor() { + public void elementVisited(PathMap.Element element) { + evict((LRUEntry) element.get(), false); + } + }, false); + element.remove(false); + } else { + idCache.remove(entry.getId()); + entry.remove(); + } + } + } + + /** + * Evict item from cache. Evicts the associated LRUEntry + * and the PathMap.Element with it. Indexes of same name + * sibling elements are not shifted! + * + * @param id item id + */ + private void evict(ItemId id) { + synchronized (cacheMonitor) { + LRUEntry entry = (LRUEntry) idCache.get(id); + if (entry != null) { + evict(entry, true); + } + } + } + + /** + * Remove path map element from cache. This will traverse all children + * of this element and remove the objects associated with them. + * Index of same name sibling items are shifted! * * @param element path map element */ - private void evict(PathMap.Element element) { + private void remove(PathMap.Element element) { synchronized (cacheMonitor) { element.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { - evict((LRUEntry) element.get(), false); + remove((LRUEntry) element.get(), false); } }, false); } @@ -626,7 +681,7 @@ if (parent != null) { PathMap.Element element = parent.remove(path.getNameElement()); if (element != null) { - evict(element); + remove(element); } } } Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PathMap.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PathMap.java?rev=412712&r1=412711&r2=412712&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PathMap.java (original) +++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/PathMap.java Thu Jun 8 03:00:21 2006 @@ -310,10 +310,19 @@ /** * Remove this element. Delegates the call to the parent item. + * Index of same name siblings will be shifted! */ public void remove() { + remove(true); + } + + /** + * Remove this element. Delegates the call to the parent item. + * @param shift if index of same name siblings will be shifted. + */ + public void remove(boolean shift) { if (parent != null) { - parent.remove(getPathElement()); + parent.remove(getPathElement(), shift); } }