Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 472047ED8 for ; Mon, 5 Dec 2011 19:18:11 +0000 (UTC) Received: (qmail 15330 invoked by uid 500); 5 Dec 2011 19:18:11 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 15287 invoked by uid 500); 5 Dec 2011 19:18:11 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 15280 invoked by uid 99); 5 Dec 2011 19:18:11 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Dec 2011 19:18:11 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Dec 2011 19:18:06 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E302E2388A2C for ; Mon, 5 Dec 2011 19:17:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1210585 - in /directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl: AvlTable.java AvlTableDupsCursor.java Date: Mon, 05 Dec 2011 19:17:43 -0000 To: commits@directory.apache.org From: saya@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111205191743.E302E2388A2C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: saya Date: Mon Dec 5 19:17:43 2011 New Revision: 1210585 URL: http://svn.apache.org/viewvc?rev=1210585&view=rev Log: Changed avl table to use ConcurrentNavigableMap, and OrderedSet and its cursor. TODO: I will add a multithreaded test and try to make it work with txns. Should be useful to have txns tests without the effect of interceptors. Modified: directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java Modified: directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java?rev=1210585&r1=1210584&r2=1210585&view=diff ============================================================================== --- directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java (original) +++ directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java Mon Dec 5 19:17:43 2011 @@ -21,15 +21,16 @@ package org.apache.directory.server.xdbm import java.util.Comparator; +import java.util.Map; +import java.util.concurrent.ConcurrentNavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; -import org.apache.directory.server.core.avltree.AvlSingletonOrOrderedSetCursor; -import org.apache.directory.server.core.avltree.AvlTree; import org.apache.directory.server.core.avltree.AvlTreeCursor; -import org.apache.directory.server.core.avltree.AvlTreeMap; -import org.apache.directory.server.core.avltree.AvlTreeMapImpl; import org.apache.directory.server.core.avltree.AvlTreeMapNoDupsWrapperCursor; +import org.apache.directory.server.core.avltree.ConcurrentMapCursor; import org.apache.directory.server.core.avltree.KeyTupleAvlCursor; -import org.apache.directory.server.core.avltree.LinkedAvlMapNode; +import org.apache.directory.server.core.avltree.OrderedSet; +import org.apache.directory.server.core.avltree.OrderedSetCursor; import org.apache.directory.server.core.avltree.SingletonOrOrderedSet; import org.apache.directory.server.core.api.partition.index.AbstractTable; import org.apache.directory.shared.ldap.model.cursor.Cursor; @@ -45,14 +46,16 @@ import org.apache.directory.shared.ldap. */ public class AvlTable extends AbstractTable { - private final AvlTreeMap avl; + private final ConcurrentNavigableMap> map; private final Comparator> keyOnlytupleComparator; + /** Whether dups is enabled */ + private boolean dupsEnabled; + public AvlTable( String name, final Comparator keyComparator, final Comparator valueComparator, boolean dupsEnabled ) { super( null, name, keyComparator, valueComparator ); - this.avl = new AvlTreeMapImpl( keyComparator, valueComparator, dupsEnabled ); this.keyOnlytupleComparator = new Comparator>() { public int compare( Tuple t0, Tuple t1 ) @@ -60,6 +63,15 @@ public class AvlTable extends Abst return keyComparator.compare( t0.getKey(), t1.getKey() ); } }; + + map = new ConcurrentSkipListMap>( keyComparator ); + this.dupsEnabled = dupsEnabled; + } + + + public ConcurrentNavigableMap> getBackingMap() + { + return map; } @@ -68,7 +80,7 @@ public class AvlTable extends Abst */ public void close() throws Exception { - ( ( AvlTreeMapImpl ) avl ).removeAll(); + map.clear(); } @@ -82,18 +94,16 @@ public class AvlTable extends Abst return 0; } - LinkedAvlMapNode node = avl.find( key ); + SingletonOrOrderedSet set = map.get( key ); - if ( node == null ) + if ( set == null ) { return 0; } - SingletonOrOrderedSet val = node.getValue(); - - if ( val.isOrderedSet() ) + if ( set.isOrderedSet() ) { - return val.getOrderedSet().getSize(); + return set.getOrderedSet().getSize(); } return 1; @@ -110,21 +120,19 @@ public class AvlTable extends Abst return null; } - LinkedAvlMapNode node = avl.find( key ); + SingletonOrOrderedSet set = map.get( key ); - if ( node == null ) + if ( set == null ) { return null; } - SingletonOrOrderedSet val = node.getValue(); - - if ( val.isOrderedSet() ) + if ( set.isOrderedSet() ) { - return val.getOrderedSet().getFirst().getKey(); + return set.getOrderedSet().first(); } - return val.getSingleton(); + return set.getSingleton(); } @@ -133,7 +141,7 @@ public class AvlTable extends Abst */ public int greaterThanCount( K key ) throws Exception { - return avl.getSize(); + return count; } @@ -147,7 +155,7 @@ public class AvlTable extends Abst return false; } - return avl.find( key ) != null; + return ( map.get( key ) != null ); } @@ -156,12 +164,31 @@ public class AvlTable extends Abst */ public boolean has( K key, V value ) throws Exception { - if ( key == null ) + if ( key == null || value == null ) + { + return false; + } + + SingletonOrOrderedSet set = map.get( key ); + + if ( set == null ) { return false; } - return avl.find( key, value ) != null; + if ( set.isOrderedSet() ) + { + return set.getOrderedSet().contains( value ); + } + + V singletonValue = set.getSingleton(); + + if ( valueComparator.compare( singletonValue, value ) == 0 ) + { + return true; + } + + return false; } @@ -175,7 +202,7 @@ public class AvlTable extends Abst return false; } - return avl.findGreaterOrEqual( key ) != null; + return ( map.ceilingKey( key ) != null ); } @@ -189,20 +216,37 @@ public class AvlTable extends Abst return false; } - LinkedAvlMapNode node = avl.findGreaterOrEqual( key ); + Map.Entry> entry = map.lastEntry(); + + if ( entry == null ) + { + return false; + } + + K lastKey = entry.getKey(); + SingletonOrOrderedSet lastSet = entry.getValue(); + + // Null values shouldnt be allowed + if ( lastSet == null ) + { + throw new RuntimeException( "AvlTable: Null value in map for key: " + lastKey ); + } - if ( node == null ) + if ( keyComparator.compare( lastKey, key ) > 0 ) + { + return true; + } + else if ( keyComparator.compare( lastKey, key ) < 0 ) { return false; } - if ( node.getValue().isOrderedSet() ) + if ( lastSet.isOrderedSet() ) { - AvlTree values = node.getValue().getOrderedSet(); - return values.findGreaterOrEqual( val ) != null; + return lastSet.getOrderedSet().hasGreaterOrEqual( val ); } - return valueComparator.compare( node.getValue().getSingleton(), val ) >= 0; + return valueComparator.compare( lastSet.getSingleton(), val ) >= 0; } @@ -216,7 +260,7 @@ public class AvlTable extends Abst return false; } - return avl.findLessOrEqual( key ) != null; + return ( map.floorEntry( key ) != null ); } @@ -230,20 +274,37 @@ public class AvlTable extends Abst return false; } - LinkedAvlMapNode node = avl.findLessOrEqual( key ); + Map.Entry> entry = map.firstEntry(); - if ( node == null ) + if ( entry == null ) { return false; } - if ( node.getValue().isOrderedSet() ) + K firstKey = entry.getKey(); + SingletonOrOrderedSet firstSet = entry.getValue(); + + // Null values shouldnt be allowed + if ( firstSet == null ) + { + throw new RuntimeException( "AvlTable: Null value in map for key: " + firstKey ); + } + + if ( keyComparator.compare( firstKey, key ) < 0 ) { - AvlTree values = node.getValue().getOrderedSet(); - return values.findLessOrEqual( val ) != null; + return true; + } + else if ( keyComparator.compare( firstKey, key ) > 0 ) + { + return false; } - return valueComparator.compare( node.getValue().getSingleton(), val ) <= 0; + if ( firstSet.isOrderedSet() ) + { + return firstSet.getOrderedSet().hasLessOrEqual( val ); + } + + return valueComparator.compare( firstSet.getSingleton(), val ) <= 0; } @@ -252,7 +313,7 @@ public class AvlTable extends Abst */ public boolean isDupsEnabled() { - return avl.isDupsAllowed(); + return dupsEnabled; } @@ -268,40 +329,74 @@ public class AvlTable extends Abst /** * {@inheritDoc} */ - public void put( K key, V value ) throws Exception + public synchronized void put( K key, V value ) throws Exception { if ( key == null || value == null ) { return; } - if ( avl.insert( key, value ) == null ) + SingletonOrOrderedSet set = map.get( key ); + + if ( set == null ) { + + if ( dupsEnabled ) + { + OrderedSet orderedSet = new OrderedSet( valueComparator ); + orderedSet.insert( value ); + set = new SingletonOrOrderedSet( orderedSet ); + } + else + { + set = new SingletonOrOrderedSet( value ); + } + + map.put( key, set ); count++; + + return; + } + + if ( set.isOrderedSet() ) + { + if ( set.getOrderedSet().insert( value ) == true ) + { + count++; + } + + return; } + + // Replace existing value + set.setSingleton( value ); + + return; } /** * {@inheritDoc} */ - public void remove( K key ) throws Exception + public synchronized void remove( K key ) throws Exception { if ( key == null ) { return; } - SingletonOrOrderedSet value = avl.remove( key ); + SingletonOrOrderedSet set = map.get( key ); - if ( value == null ) + if ( set == null ) { return; } - - if ( value.isOrderedSet() ) + + map.remove( key ); + + if ( set.isOrderedSet() ) { - count -= value.getOrderedSet().getSize(); + count -= set.getOrderedSet().getSize(); } else { @@ -313,12 +408,38 @@ public class AvlTable extends Abst /** * {@inheritDoc} */ - public void remove( K key, V value ) throws Exception + public synchronized void remove( K key, V value ) throws Exception { - if ( avl.remove( key, value ) != null ) + if ( key == null || value == null ) + { + return; + } + + SingletonOrOrderedSet set = map.get( key ); + + if ( set == null ) { - count--; + return; } + + if ( set.isOrderedSet() ) + { + if ( set.getOrderedSet().remove( value ) == true ) + { + count --; + + if ( set.getOrderedSet().getSize() == 0 ) + { + map.remove( key ); + } + } + + return; + } + + // Remove singleton value + map.remove( key ); + count--; } @@ -327,9 +448,9 @@ public class AvlTable extends Abst */ public Cursor> cursor() throws Exception { - if ( ! avl.isDupsAllowed() ) + if ( ! dupsEnabled ) { - return new AvlTreeMapNoDupsWrapperCursor( new AvlSingletonOrOrderedSetCursor( avl ) ); + return new AvlTreeMapNoDupsWrapperCursor( new ConcurrentMapCursor>( map ) ); } return new AvlTableDupsCursor( this ); @@ -346,19 +467,19 @@ public class AvlTable extends Abst return new EmptyCursor>(); } - LinkedAvlMapNode node = avl.find( key ); + SingletonOrOrderedSet set = map.get( key ); - if ( node == null ) + if ( set == null ) { return new EmptyCursor>(); } - if ( node.getValue().isOrderedSet() ) + if ( set.isOrderedSet() ) { - return new KeyTupleAvlCursor( node.getValue().getOrderedSet(), key ); + return new KeyTupleAvlCursor( set.getOrderedSet(), key ); } - return new SingletonCursor>( new Tuple( key, node.getValue().getSingleton() ), + return new SingletonCursor>( new Tuple( key, set.getSingleton() ), keyOnlytupleComparator ); } @@ -373,30 +494,19 @@ public class AvlTable extends Abst return new EmptyCursor(); } - LinkedAvlMapNode node = avl.find( key ); + SingletonOrOrderedSet set = map.get( key ); - if ( node == null ) + if ( set == null ) { return new EmptyCursor(); } - if ( node.getValue().isOrderedSet() ) + if ( set.isOrderedSet() ) { - return new AvlTreeCursor( node.getValue().getOrderedSet() ); + return new OrderedSetCursor( set.getOrderedSet() ); } - return new SingletonCursor( node.getValue().getSingleton(), valueComparator ); + return new SingletonCursor( set.getSingleton(), valueComparator ); } - - /** - * Returns the internal AvlTreeMap so other classes like Cursors - * in the same package can access it. - * - * @return AvlTreeMap used to store Tuples - */ - AvlTreeMap getAvlTreeMap() - { - return avl; - } } Modified: directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java?rev=1210585&r1=1210584&r2=1210585&view=diff ============================================================================== --- directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java (original) +++ directory/apacheds/branches/apacheds-txns/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java Mon Dec 5 19:17:43 2011 @@ -20,9 +20,10 @@ package org.apache.directory.server.xdbm.impl.avl; -import org.apache.directory.server.core.avltree.AvlSingletonOrOrderedSetCursor; -import org.apache.directory.server.core.avltree.AvlTree; import org.apache.directory.server.core.avltree.AvlTreeCursor; +import org.apache.directory.server.core.avltree.ConcurrentMapCursor; +import org.apache.directory.server.core.avltree.OrderedSet; +import org.apache.directory.server.core.avltree.OrderedSetCursor; import org.apache.directory.server.core.avltree.SingletonOrOrderedSet; import org.apache.directory.shared.ldap.model.cursor.AbstractTupleCursor; import org.apache.directory.shared.ldap.model.cursor.Cursor; @@ -51,7 +52,7 @@ public class AvlTableDupsCursor ext * The underlying wrapped cursor which returns Tuples whose values are * either V objects or AvlTree objects. */ - private final AvlSingletonOrOrderedSetCursor wrappedCursor; + private final ConcurrentMapCursor> wrappedCursor; /** * A Cursor over a set of value objects for the current key held in the @@ -84,7 +85,7 @@ public class AvlTableDupsCursor ext public AvlTableDupsCursor( AvlTable table ) { this.table = table; - this.wrappedCursor = new AvlSingletonOrOrderedSetCursor( table.getAvlTreeMap() ); + this.wrappedCursor = new ConcurrentMapCursor>( table.getBackingMap() ); LOG.debug( "Created on table {}", table.getName() ); } @@ -121,13 +122,13 @@ public class AvlTableDupsCursor ext if ( wrappedTuple.getValue().isOrderedSet() ) { - AvlTree avlTree = wrappedTuple.getValue().getOrderedSet(); - dupsCursor = new AvlTreeCursor( avlTree ); + OrderedSet orderedSet = wrappedTuple.getValue().getOrderedSet(); + dupsCursor = new OrderedSetCursor( orderedSet ); } else { dupsCursor = new SingletonCursor( - wrappedTuple.getValue().getSingleton(), wrappedCursor.getValuComparator() ); + wrappedTuple.getValue().getSingleton(), table.getValueComparator() ); } if ( value == null ) @@ -209,12 +210,12 @@ public class AvlTableDupsCursor ext if ( values.isOrderedSet() ) { - AvlTree set = values.getOrderedSet(); - dupsCursor = new AvlTreeCursor( set ); + OrderedSet set = values.getOrderedSet(); + dupsCursor = new OrderedSetCursor( set ); } else { - dupsCursor = new SingletonCursor( values.getSingleton(), wrappedCursor.getValuComparator() ); + dupsCursor = new SingletonCursor( values.getSingleton(), table.getValueComparator() ); } if ( value == null ) @@ -301,11 +302,11 @@ public class AvlTableDupsCursor ext if ( values.isOrderedSet() ) { - dupsCursor = new AvlTreeCursor( values.getOrderedSet() ); + dupsCursor = new OrderedSetCursor( values.getOrderedSet() ); } else { - dupsCursor = new SingletonCursor( values.getSingleton(), wrappedCursor.getValuComparator() ); + dupsCursor = new SingletonCursor( values.getSingleton(), table.getValueComparator() ); } /* @@ -356,11 +357,11 @@ public class AvlTableDupsCursor ext if ( values.isOrderedSet() ) { - dupsCursor = new AvlTreeCursor( values.getOrderedSet() ); + dupsCursor = new OrderedSetCursor( values.getOrderedSet() ); } else { - dupsCursor = new SingletonCursor( values.getSingleton(), wrappedCursor.getValuComparator() ); + dupsCursor = new SingletonCursor( values.getSingleton(), table.getValueComparator() ); } /* @@ -402,11 +403,11 @@ public class AvlTableDupsCursor ext if ( values.isOrderedSet()) { - dupsCursor = new AvlTreeCursor( values.getOrderedSet() ); + dupsCursor = new OrderedSetCursor( values.getOrderedSet() ); } else { - dupsCursor = new SingletonCursor( values.getSingleton(), wrappedCursor.getValuComparator() ); + dupsCursor = new SingletonCursor( values.getSingleton(), table.getValueComparator() ); } /* @@ -462,11 +463,11 @@ public class AvlTableDupsCursor ext if ( values.isOrderedSet() ) { - dupsCursor = new AvlTreeCursor( values.getOrderedSet() ); + dupsCursor = new OrderedSetCursor( values.getOrderedSet() ); } else { - dupsCursor = new SingletonCursor( values.getSingleton(), wrappedCursor.getValuComparator() ); + dupsCursor = new SingletonCursor( values.getSingleton(), table.getValueComparator() ); } /*