Author: mduerig Date: Thu May 10 09:52:03 2012 New Revision: 1336567 URL: http://svn.apache.org/viewvc?rev=1336567&view=rev Log: OAK-93: Tree has wrong parent after move - proper synchronization - weak ref. children
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java?rev=1336567&r1=1336566&r2=1336567&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java (original) +++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeImpl.java Thu May 10 09:52:03 2012 @@ -18,6 +18,7 @@ */ package org.apache.jackrabbit.oak.core; +import org.apache.commons.collections.map.ReferenceMap; import org.apache.jackrabbit.oak.api.CoreValue; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Tree; @@ -30,10 +31,12 @@ import org.apache.jackrabbit.oak.spi.sta import org.apache.jackrabbit.oak.util.Function1; import org.apache.jackrabbit.oak.util.Iterators; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Implementation of tree based on {@link NodeStateBuilder}s. Each subtree @@ -62,8 +65,7 @@ public class TreeImpl implements Tree { /** Name of this tree */ private String name; - // FIXME: should be synchronized, and weak refs - private final Map<String, TreeImpl> children = new HashMap<String, TreeImpl>(); + private final Children children = new Children(); private TreeImpl(NodeStore store, NodeState baseState, NodeStateBuilder rootBuilder, TreeImpl parent, String name, Listener listener) { @@ -501,4 +503,47 @@ public class TreeImpl implements Tree { return !isDirty[0]; } + private static class Children { + @SuppressWarnings("unchecked") + private final Map<String, TreeImpl> children = new ReferenceMap(); + private final Lock readLock; + private final Lock writeLock; + + { + ReadWriteLock lock = new ReentrantReadWriteLock(); + readLock = lock.readLock(); + writeLock = lock.writeLock(); + } + + public void put(String name, TreeImpl tree) { + writeLock.lock(); + try { + children.put(name, tree); + } + finally { + writeLock.unlock(); + } + } + + public TreeImpl get(String name) { + readLock.lock(); + try { + return children.get(name); + } + finally { + readLock.unlock(); + } + } + + public void remove(String name) { + writeLock.lock(); + try { + children.remove(name); + } + finally { + writeLock.unlock(); + } + } + } + }