directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kayyag...@apache.org
Subject svn commit: r1482179 [2/3] - in /directory/apacheds/trunk/mavibot-partition: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/directory/ src/main/java/org/apache/directory/server/ src/main/java/org/...
Date Tue, 14 May 2013 03:09:54 GMT
Added: directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndex.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndex.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndex.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndex.java Tue May 14 03:09:53 2013
@@ -0,0 +1,131 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.MatchingRule;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.server.constants.ApacheSchemaConstants;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.ParentIdAndRdn;
+import org.apache.mavibot.btree.BTreeConfiguration;
+import org.apache.mavibot.btree.RecordManager;
+import org.apache.mavibot.btree.serializer.StringSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A special index which stores Rdn objects.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotRdnIndex extends MavibotIndex<ParentIdAndRdn, Entry>
+{
+
+    /** A logger for this class */
+    private static final Logger LOG = LoggerFactory.getLogger( MavibotRdnIndex.class );
+
+
+    public MavibotRdnIndex( RecordManager recordMan )
+    {
+        super( recordMan, ApacheSchemaConstants.APACHE_RDN_AT_OID, true );
+        initialized = false;
+    }
+
+
+    public void init( SchemaManager schemaManager, AttributeType attributeType ) throws IOException
+    {
+        LOG.debug( "Initializing an Index for attribute '{}'", attributeType.getName() );
+
+        this.attributeType = attributeType;
+
+        if ( attributeId == null )
+        {
+            setAttributeId( attributeType.getName() );
+        }
+
+        if ( this.wkDirPath == null )
+        {
+            NullPointerException e = new NullPointerException( "The index working directory has not be set" );
+
+            e.printStackTrace();
+            throw e;
+        }
+
+        String path = new File( this.wkDirPath, attributeType.getOid() ).getAbsolutePath();
+
+        try
+        {
+            initTables( schemaManager );
+        }
+        catch ( IOException e )
+        {
+            // clean up
+            close();
+            throw e;
+        }
+
+        // finally write a text file in the format <OID>-<attribute-name>.txt
+        FileWriter fw = new FileWriter( new File( path + "-" + attributeType.getName() + ".txt" ) );
+
+        // write the AttributeType description
+        fw.write( attributeType.toString() );
+        fw.close();
+
+        initialized = true;
+    }
+
+
+    /**
+     * Initializes the forward and reverse tables used by this Index.
+     * 
+     * @param schemaManager The server schemaManager
+     * @throws IOException if we cannot initialize the forward and reverse
+     * tables
+     * @throws NamingException
+     */
+    private void initTables( SchemaManager schemaManager ) throws IOException
+    {
+        MatchingRule mr = attributeType.getEquality();
+
+        if ( mr == null )
+        {
+            throw new IOException( I18n.err( I18n.ERR_574, attributeType.getName() ) );
+        }
+
+        MavibotParentIdAndRdnSerializer.setSchemaManager( schemaManager );
+        MavibotParentIdAndRdnSerializer parentIdAndSerializer = new MavibotParentIdAndRdnSerializer();
+
+        String forwardTableName = attributeType.getOid() + FORWARD_BTREE;
+        forward = new MavibotTable<ParentIdAndRdn, String>( recordMan, schemaManager, forwardTableName, parentIdAndSerializer, new StringSerializer(), false );
+
+        String reverseTableName = attributeType.getOid() + REVERSE_BTREE;
+        reverse = new MavibotTable<String, ParentIdAndRdn>( recordMan, schemaManager, reverseTableName, new StringSerializer(), parentIdAndSerializer, false );
+    }
+}

Added: directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotTable.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotTable.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotTable.java Tue May 14 03:09:53 2013
@@ -0,0 +1,534 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ * 
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import java.io.IOException;
+
+import org.apache.directory.api.ldap.model.cursor.Cursor;
+import org.apache.directory.api.ldap.model.cursor.EmptyCursor;
+import org.apache.directory.api.ldap.model.cursor.SingletonCursor;
+import org.apache.directory.api.ldap.model.cursor.Tuple;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.server.core.avltree.ArrayMarshaller;
+import org.apache.directory.server.core.avltree.ArrayTree;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.AbstractTable;
+import org.apache.mavibot.btree.BTree;
+import org.apache.mavibot.btree.RecordManager;
+import org.apache.mavibot.btree.exception.BTreeAlreadyManagedException;
+import org.apache.mavibot.btree.serializer.ElementSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotTable<K, V> extends AbstractTable<K, V>
+{
+
+    private BTree<K,V> bt;
+
+    private ArrayMarshaller<V> arrayMarshaller;
+    
+    /** A logger for this class */
+    private static final Logger LOG = LoggerFactory.getLogger( MavibotTable.class );
+
+    protected RecordManager recordMan;
+    
+    public MavibotTable( RecordManager recordMan, SchemaManager schemaManager, String name, ElementSerializer<K> keySerializer, ElementSerializer<V> valueSerializer, boolean allowDuplicates ) throws IOException
+    {
+        super( schemaManager, name, keySerializer.getComparator(), valueSerializer.getComparator() );
+        this.recordMan = recordMan;
+        
+        bt = recordMan.getManagedTree( name );
+        
+        if( bt == null )
+        {
+            bt = new BTree<K, V>( name, keySerializer, valueSerializer, allowDuplicates );
+            
+            try
+            {
+                recordMan.manage( bt );
+            }
+            catch( BTreeAlreadyManagedException e )
+            {
+                // should never happen
+                throw new RuntimeException( e );
+            }
+        }
+        
+        this.allowsDuplicates = allowDuplicates;
+        arrayMarshaller = new ArrayMarshaller<V>( valueComparator );
+    }
+
+
+    @Override
+    public boolean isDupsEnabled()
+    {
+        return allowsDuplicates;
+    }
+
+
+    @Override
+    public boolean has( K key ) throws IOException
+    {
+        return bt.hasKey( key );
+    }
+
+
+    @Override
+    public boolean has( K key, V value ) throws LdapException
+    {
+        try
+        {
+            return bt.contains( key, value );
+        }
+        catch ( IOException e )
+        {
+            throw new LdapException( e );
+        }
+    }
+
+
+    @Override
+    public boolean hasGreaterOrEqual( K key ) throws Exception
+    {
+        org.apache.mavibot.btree.Cursor<K,V> cursor = null;
+        try
+        {
+            cursor = bt.browseFrom( key );
+            
+            return cursor.hasNext();
+        }
+        finally
+        {
+            if( cursor != null )
+            {
+                cursor.close();
+            }
+        }
+    }
+
+
+    @Override
+    public boolean hasLessOrEqual( K key ) throws Exception
+    {
+        org.apache.mavibot.btree.Cursor<K,V> cursor = null;
+        
+        try
+        {
+            cursor = bt.browseFrom( key );
+            
+            org.apache.mavibot.btree.Tuple<K,V> tuple = null;
+            
+            if( cursor.hasNext() )
+            {
+                tuple = cursor.next();
+            }
+            
+            // Test for equality first since it satisfies both greater/less than
+            if ( null != tuple && keyComparator.compare( ( K ) tuple.getKey(), key ) == 0 )
+            {
+                return true;
+            }
+            
+            if( null == tuple )
+            {
+                return count > 0;
+            }
+            else
+            {
+                if( cursor.hasPrev() )
+                {
+                    return true;   
+                }
+            }
+            
+            return false;
+        }
+        finally
+        {
+            if( cursor != null )
+            {
+                cursor.close();
+            }
+        }
+    }
+
+
+    @Override
+    public boolean hasGreaterOrEqual( K key, V val ) throws LdapException
+    {
+        if ( key == null )
+        {
+            return false;
+        }
+
+        if ( !allowsDuplicates )
+        {
+            throw new UnsupportedOperationException( I18n.err( I18n.ERR_593 ) );
+        }
+
+        org.apache.mavibot.btree.Cursor<V,V> cursor = null;
+        
+        try
+        {
+            if( !bt.hasKey( key ) )
+            {
+                return false;
+            }
+            
+            BTree<V,V> dups = bt.getValues( key );
+
+            cursor = dups.browseFrom( val );
+            
+            return cursor.hasNext();
+        }
+        catch ( Exception e )
+        {
+            throw new LdapException( e );
+        }
+        finally
+        {
+            if( cursor != null )
+            {
+                cursor.close();
+            }
+        }
+    }
+
+
+    @Override
+    public boolean hasLessOrEqual( K key, V val ) throws Exception
+    {
+        if ( key == null )
+        {
+            return false;
+        }
+
+        if ( !allowsDuplicates )
+        {
+            throw new UnsupportedOperationException( I18n.err( I18n.ERR_593 ) );
+        }
+
+        if( !bt.hasKey( key ) )
+        {
+            return false;
+        }
+        
+        BTree<V,V> dups = bt.getValues( key );
+
+        org.apache.mavibot.btree.Cursor<V,V> cursor = null;
+        
+        try
+        {
+            cursor = dups.browseFrom( val );
+            
+            org.apache.mavibot.btree.Tuple<V,V> tuple = null;
+            
+            if( cursor.hasNext() )
+            {
+                tuple = cursor.next();
+            }
+            
+            // Test for equality first since it satisfies both greater/less than
+            if ( null != tuple && keyComparator.compare( ( K ) tuple.getKey(), key ) == 0 )
+            {
+                return true;
+            }
+            
+            if( null == tuple )
+            {
+                return count > 0;
+            }
+            else
+            {
+                if( cursor.hasPrev() )
+                {
+                    return true;   
+                }
+            }
+            
+            return false;
+        }
+        finally
+        {
+            if( cursor != null )
+            {
+                cursor.close();
+            }
+        }
+    }
+
+
+    @Override
+    public V get( K key ) throws LdapException
+    {
+        if ( key == null )
+        {
+            return null;
+        }
+
+        try
+        {
+            if( bt.hasKey( key ) )
+            {
+                return bt.get( key );
+            }
+        }
+        catch( Exception e )
+        {
+            throw new LdapException( e );
+        }
+        
+        return null;
+    }
+
+
+    @Override
+    public void put( K key, V value ) throws Exception
+    {
+        try
+        {
+            if ( ( value == null ) || ( key == null ) )
+            {
+                throw new IllegalArgumentException( I18n.err( I18n.ERR_594 ) );
+            }
+
+            V replaced = bt.insert( key, value );
+            if( replaced == null )
+            {
+                count++;
+            }
+        }
+        catch ( Exception e )
+        {
+            LOG.error( I18n.err( I18n.ERR_131, key, name ), e );
+            throw e;
+        }
+    }
+
+
+    @Override
+    public void remove( K key ) throws Exception
+    {
+        try
+        {
+            if ( key == null )
+            {
+                return;
+            }
+
+            org.apache.mavibot.btree.Tuple<K,V> returned = bt.delete( key );
+
+            if ( null == returned )
+            {
+                return;
+            }
+
+            this.count--;
+        }
+        catch ( Exception e )
+        {
+            LOG.error( I18n.err( I18n.ERR_133, key, name ), e );
+
+            if ( e instanceof IOException )
+            {
+                throw ( IOException ) e;
+            }
+        }
+    }
+
+
+    @Override
+    public void remove( K key, V value ) throws Exception
+    {
+        try
+        {
+            if ( key == null )
+            {
+                return;
+            }
+
+            org.apache.mavibot.btree.Tuple<K,V> t = bt.delete( key, value );
+            
+            if( t != null )
+            {
+                count--;
+            }
+        }
+        catch ( Exception e )
+        {
+            LOG.error( I18n.err( I18n.ERR_132, key, value, name ), e );
+        }
+    }
+
+
+    @Override
+    public Cursor<Tuple<K, V>> cursor() throws LdapException
+    {
+        return new MavibotCursor<K, V>( this );
+    }
+
+
+    @Override
+    public Cursor<Tuple<K, V>> cursor( K key ) throws LdapException
+    {
+        if ( key == null )
+        {
+            return new EmptyCursor<Tuple<K, V>>();
+        }
+
+        try
+        {
+            if ( !bt.hasKey( key ) )
+            {
+                return new EmptyCursor<Tuple<K, V>>();
+            }
+            
+            
+            if ( !allowsDuplicates )
+            {
+                V val = bt.get( key );
+                return new SingletonCursor<Tuple<K, V>>(
+                    new Tuple<K, V>( key, val ) );
+            }
+            
+            BTree<V,V> dups = bt.getValues( key );
+            
+            return new KeyTupleArrayCursor<K, V>( dups, key );
+        }
+        catch( Exception e )
+        {
+            throw new LdapException( e );
+        }
+    }
+
+
+    @Override
+    public Cursor<V> valueCursor( K key ) throws Exception
+    {
+        if ( key == null )
+        {
+            return new EmptyCursor<V>();
+        }
+
+        try
+        {
+            if ( !bt.hasKey( key ) )
+            {
+                return new EmptyCursor<V>();
+            }
+            
+            
+            if ( !allowsDuplicates )
+            {
+                V val = bt.get( key );
+                return new SingletonCursor<V>( val );
+            }
+            
+            BTree<V,V> dups = bt.getValues( key );
+            
+            return new ValueTreeCursor<V>( dups );
+        }
+        catch( Exception e )
+        {
+            throw new LdapException( e );
+        }
+    }
+
+
+    @Override
+    public int count( K key ) throws Exception
+    {
+        if ( key == null )
+        {
+            return 0;
+        }
+
+        if ( bt.hasKey( key ) )
+        {
+            if ( !allowsDuplicates )
+            {
+                return 1;
+            }
+            else
+            {
+                BTree<V,V> values = bt.getValues( key );
+                return ( int ) values.getNbElems();
+            }
+        }
+
+        return 0;
+    }
+
+
+    @Override
+    public int greaterThanCount( K key ) throws Exception
+    {
+        // take a best guess
+        return Math.min( count, 10 );
+    }
+
+
+    @Override
+    public int lessThanCount( K key ) throws Exception
+    {
+        // take a best guess
+        return Math.min( count, 10 );
+     }
+
+
+    @Override
+    public void close() throws Exception
+    {
+        // do nothing here, the RecordManager will be closed in MavibotMasterTable.close()
+    }
+
+    public ArrayTree<V> getDupsContainer( byte[] serialized ) throws IOException
+    {
+        if ( serialized == null )
+        {
+            return new ArrayTree<V>( valueComparator );
+        }
+
+        return arrayMarshaller.deserialize( serialized );
+    }
+
+
+	protected BTree<K, V> getBTree() 
+	{
+		return bt;
+	}
+	
+	
+    /**
+     * Synchronizes the buffers with disk.
+     *
+     * @throws IOException if errors are encountered on the flush
+     */
+    public synchronized void sync() throws IOException
+    {
+        bt.flush();
+    }	
+}

Added: directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/ValueTreeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/ValueTreeCursor.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/ValueTreeCursor.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/mavibot/ValueTreeCursor.java Tue May 14 03:09:53 2013
@@ -0,0 +1,135 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+import java.io.IOException;
+
+import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.mavibot.btree.BTree;
+
+/**
+ * TODO ValueTreeCursor.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ValueTreeCursor<V> extends AbstractCursor<V>
+{
+
+    private org.apache.mavibot.btree.Cursor<V, V> wrapped;
+    
+    private V available;
+
+    // marker to detect the availability (cause Mavibot supports null values also)
+    private V NOT_AVAILABLE = ( V ) new Object();
+    
+    public ValueTreeCursor( BTree<V,V> dupsTree )
+    {
+        try
+        {
+            this.wrapped = dupsTree.browse();
+        }
+        catch( IOException e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+    
+    @Override
+    public boolean available()
+    {
+        return ( available != NOT_AVAILABLE );
+    }
+
+    @Override
+    public void before( V element ) throws LdapException, CursorException, IOException
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+    }
+
+    @Override
+    public void after( V element ) throws LdapException, CursorException, IOException
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );        
+    }
+
+    @Override
+    public void beforeFirst() throws LdapException, CursorException, IOException
+    {
+    }
+
+    @Override
+    public void afterLast() throws LdapException, CursorException, IOException
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );        
+    }
+
+    @Override
+    public boolean first() throws LdapException, CursorException, IOException
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+    }
+
+    @Override
+    public boolean last() throws LdapException, CursorException, IOException
+    {
+        throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+    }
+
+    @Override
+    public boolean previous() throws LdapException, CursorException, IOException
+    {
+        if( wrapped.hasPrev() )
+        {
+            available = wrapped.prev().getKey();
+            return true;
+        }
+        else
+        {
+            available = NOT_AVAILABLE;
+            return false;
+        }
+    }
+
+    @Override
+    public boolean next() throws LdapException, CursorException, IOException
+    {
+        if( wrapped.hasNext() )
+        {
+            available = wrapped.next().getKey();
+            return true;
+        }
+        else
+        {
+            available = NOT_AVAILABLE;
+            return false;
+        }
+    }
+
+    @Override
+    public V get() throws CursorException, IOException
+    {
+        return available;
+    }
+
+}

Added: directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotEntrySerializationTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotEntrySerializationTest.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotEntrySerializationTest.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotEntrySerializationTest.java Tue May 14 03:09:53 2013
@@ -0,0 +1,142 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaloader.LdifSchemaLoader;
+import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.api.util.exception.Exceptions;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+
+/**
+ * Test the Entry Serialization
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class MavibotEntrySerializationTest
+{
+
+    private MavibotEntrySerializer serializer = new MavibotEntrySerializer();
+    
+    private static SchemaManager schemaManager;
+    
+    @BeforeClass
+    public static void init() throws Exception
+    {
+        String workingDirectory = System.getProperty( "workingDirectory" );
+
+        if ( workingDirectory == null )
+        {
+            String path = MavibotIndexTest.class.getResource( "" ).getPath();
+            int targetPos = path.indexOf( "target" );
+            workingDirectory = path.substring( 0, targetPos + 6 );
+        }
+
+        File schemaRepository = new File( workingDirectory, "schema" );
+        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+        extractor.extractOrCopy( true );
+        LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
+        schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabled();
+
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+        
+        MavibotEntrySerializer.setSchemaManager( schemaManager );
+    }
+
+
+    @Test
+    public void testEntryFullSerialization() throws IOException, LdapException, ClassNotFoundException
+    {
+        Entry entry1 = new DefaultEntry( schemaManager, 
+            "dc=example",
+            "ObjectClass: top",
+            "ObjectClass: domain",
+            "dc: example",
+            "l: test" );
+        
+        byte[] data = serializer.serialize( entry1 );
+        
+        Entry entry2 = serializer.deserialize( ByteBuffer.wrap( data ) );
+
+        assertEquals( entry1, entry2 );
+        assertTrue( entry2.contains( "ObjectClass", "top", "domain" ) );
+    }
+
+
+    @Test
+    public void testPlainEntryFullSerialization() throws IOException, LdapException, ClassNotFoundException
+    {
+        Entry entry1 = new DefaultEntry(
+            "dc=example, dc=com",
+            "ObjectClass: top",
+            "ObjectClass: domain",
+            "dc: example",
+            "l: test" );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream( baos );
+
+        entry1.writeExternal( out );
+
+        ObjectInputStream in = null;
+
+        byte[] data = baos.toByteArray();
+        in = new ObjectInputStream( new ByteArrayInputStream( data ) );
+
+        Entry entry2 = new DefaultEntry();
+        entry2.readExternal( in );
+
+        assertEquals( entry1, entry2 );
+        assertTrue( entry2.contains( "ObjectClass", "top", "domain" ) );
+    }
+
+}

Added: directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotIndexTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotIndexTest.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotIndexTest.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotIndexTest.java Tue May 14 03:09:53 2013
@@ -0,0 +1,534 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.Cursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaloader.LdifSchemaLoader;
+import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.api.util.exception.Exceptions;
+import org.apache.directory.server.xdbm.Index;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.mavibot.btree.RecordManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * Tests the MavibotIndex.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotIndexTest
+{
+    private static File dbFileDir;
+    Index<String, Entry, String> idx;
+    private static SchemaManager schemaManager;
+
+    private RecordManager recordMan;
+
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+    
+    @BeforeClass
+    public static void init() throws Exception
+    {
+        String workingDirectory = System.getProperty( "workingDirectory" );
+
+        if ( workingDirectory == null )
+        {
+            String path = MavibotIndexTest.class.getResource( "" ).getPath();
+            int targetPos = path.indexOf( "target" );
+            workingDirectory = path.substring( 0, targetPos + 6 );
+        }
+
+        File schemaRepository = new File( workingDirectory, "schema" );
+        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+        extractor.extractOrCopy( true );
+        LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
+        schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabled();
+
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+    }
+
+
+    @Before
+    public void setup() throws IOException
+    {
+        dbFileDir = tempFolder.newFolder( MavibotIndexTest.class.getSimpleName() );
+
+        recordMan = new RecordManager( dbFileDir.getAbsolutePath() );
+    }
+
+
+    @After
+    public void teardown() throws Exception
+    {
+        destroyIndex();
+
+        recordMan.close();
+        
+        if ( ( dbFileDir != null ) && dbFileDir.exists() )
+        {
+            FileUtils.deleteDirectory( dbFileDir );
+        }
+    }
+
+
+    void destroyIndex() throws Exception
+    {
+        if ( idx != null )
+        {
+            idx.sync();
+            idx.close();
+        }
+
+        idx = null;
+    }
+
+
+    void initIndex() throws Exception
+    {
+        AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( SchemaConstants.OU_AT );
+        MavibotIndex<String, Entry> index = new MavibotIndex<String, Entry>( recordMan, attributeType.getName(), false );
+        index.setWkDirPath( dbFileDir.toURI() );
+        initIndex( index );
+    }
+
+
+    void initIndex( MavibotIndex<String, Entry> mavibotIdx ) throws Exception
+    {
+        AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( SchemaConstants.OU_AT );
+
+        if ( mavibotIdx == null )
+        {
+            mavibotIdx = new MavibotIndex<String, Entry>( recordMan, attributeType.getName(), false );
+        }
+
+        mavibotIdx.init( schemaManager, attributeType );
+        this.idx = mavibotIdx;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Property Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testAttributeId() throws Exception
+    {
+        // uninitialized index
+        MavibotIndex<Object, Object> MavibotIndex1 = new MavibotIndex<Object, Object>( recordMan, "foo", false );
+        assertEquals( "foo", MavibotIndex1.getAttributeId() );
+
+        MavibotIndex<Object, Object> MavibotIndex2 = new MavibotIndex<Object, Object>( recordMan, "bar", false );
+        assertEquals( "bar", MavibotIndex2.getAttributeId() );
+
+        // initialized index
+        initIndex();
+
+        try
+        {
+            idx.setAttributeId( "foo" );
+            fail( "Should not be able to set attributeId after initialization." );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        assertEquals( "ou", idx.getAttributeId() );
+
+        destroyIndex();
+        MavibotIndex<String, Entry> index = new MavibotIndex<String, Entry>( recordMan, "foo", false );
+        index.setWkDirPath( dbFileDir.toURI() );
+        initIndex( index );
+        assertEquals( "foo", idx.getAttributeId() );
+    }
+
+
+    @Test
+    public void testCacheSize() throws Exception
+    {
+        // uninitialized index
+        MavibotIndex<Object, Object> MavibotIndex = new MavibotIndex<Object, Object>( recordMan, "ou", false );
+        MavibotIndex.setCacheSize( 337 );
+        assertEquals( 337, MavibotIndex.getCacheSize() );
+
+        // initialized index
+        initIndex();
+
+        try
+        {
+            idx.setCacheSize( 30 );
+            fail( "Should not be able to set cacheSize after initialization." );
+        }
+        catch ( Exception e )
+        {
+        }
+        assertEquals( Index.DEFAULT_INDEX_CACHE_SIZE, idx.getCacheSize() );
+    }
+
+
+    @Test
+    public void testWkDirPath() throws Exception
+    {
+        File wkdir = new File( dbFileDir, "foo" );
+
+        // uninitialized index
+        MavibotIndex<String, Entry> MavibotIndex = new MavibotIndex<String, Entry>( recordMan, "foo", false );
+        MavibotIndex.setWkDirPath( wkdir.toURI() );
+        assertEquals( "foo", new File( MavibotIndex.getWkDirPath() ).getName() );
+
+        // initialized index
+        initIndex();
+
+        try
+        {
+            idx.setWkDirPath( wkdir.toURI() );
+            fail( "Should not be able to set wkDirPath after initialization." );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        assertEquals( dbFileDir.toURI(), idx.getWkDirPath() );
+
+        destroyIndex();
+        MavibotIndex = new MavibotIndex<String, Entry>( recordMan, "ou", false );
+        wkdir.mkdirs();
+        MavibotIndex.setWkDirPath( wkdir.toURI() );
+        initIndex( MavibotIndex );
+        assertEquals( wkdir.toURI(), idx.getWkDirPath() );
+    }
+
+
+    @Test
+    public void testGetAttribute() throws Exception
+    {
+        // uninitialized index
+        MavibotIndex<Object, Object> MavibotIndex = new MavibotIndex<Object, Object>( recordMan, "ou", false );
+        assertNull( MavibotIndex.getAttribute() );
+
+        initIndex();
+        assertEquals( schemaManager.lookupAttributeTypeRegistry( "ou" ), idx.getAttribute() );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Count Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testCount() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.count() );
+
+        idx.add( "foo", Strings.getUUID( 1234L ) );
+        assertEquals( 1, idx.count() );
+
+        idx.add( "foo", Strings.getUUID( 333L ) );
+        assertEquals( 2, idx.count() );
+
+        idx.add( "bar", Strings.getUUID( 555L ) );
+        assertEquals( 3, idx.count() );
+    }
+
+
+    @Test
+    public void testCountOneArg() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.count( "foo" ) );
+
+        idx.add( "bar", Strings.getUUID( 1234L ) );
+        assertEquals( 0, idx.count( "foo" ) );
+
+        idx.add( "foo", Strings.getUUID( 1234L ) );
+        assertEquals( 1, idx.count( "foo" ) );
+
+        idx.add( "foo", Strings.getUUID( 333L ) );
+        assertEquals( 2, idx.count( "foo" ) );
+    }
+
+
+    @Test
+    public void testGreaterThanCount() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.greaterThanCount( "a" ) );
+
+        for ( char ch = 'a'; ch <= 'z'; ch++ )
+        {
+            idx.add( String.valueOf( ch ), Strings.getUUID( ch ) );
+        }
+
+        // We should not go above the magic limit of 10
+        assertEquals( 10, idx.greaterThanCount( "a" ) );
+    }
+
+
+    @Test
+    public void testLessThanCount() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.lessThanCount( "z" ) );
+
+        for ( char ch = 'a'; ch <= 'z'; ch++ )
+        {
+            idx.add( String.valueOf( ch ), Strings.getUUID( ch ) );
+        }
+
+        // We should not go above the magic limit of 10
+        assertEquals( 10, idx.lessThanCount( "z" ) );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Add, Drop and Lookup Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testLookups() throws Exception
+    {
+        initIndex();
+        assertNull( idx.forwardLookup( "foo" ) );
+        assertNull( idx.forwardLookup( "bar" ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( -24L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 24L ) ) );
+        assertFalse( idx.forwardLessOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertFalse( idx.forwardLessOrEq( "foo", Strings.getUUID( 24L ) ) );
+        assertFalse( idx.forwardLessOrEq( "foo", Strings.getUUID( -24L ) ) );
+
+        idx.add( "foo", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+        assertTrue( idx.forward( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( -1L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( -1L ) ) );
+
+        idx.add( "foo", Strings.getUUID( 1L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+        assertTrue( idx.forward( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forward( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( -1L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 2L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 2L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( -1L ) ) );
+
+        idx.add( "bar", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "bar" ) );
+        assertTrue( idx.forward( "bar", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forward( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forward( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "bar", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( -1L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "foo", Strings.getUUID( 2L ) ) );
+        assertFalse( idx.forwardGreaterOrEq( "bar", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "bar", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 0L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( 2L ) ) );
+        assertTrue( idx.forwardLessOrEq( "foo", Strings.getUUID( -1L ) ) );
+        assertTrue( idx.forwardLessOrEq( "bar", Strings.getUUID( -1L ) ) );
+    }
+
+
+    @Test
+    public void testAddDropById() throws Exception
+    {
+        initIndex();
+        assertNull( idx.forwardLookup( "foo" ) );
+        assertNull( idx.forwardLookup( "bar" ) );
+
+        // test add/drop without adding any duplicates
+        idx.add( "foo", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+
+        idx.drop( "foo", Strings.getUUID( 0L ) );
+        assertNull( idx.forwardLookup( "foo" ) );
+
+        // test add/drop with duplicates in bulk
+        idx.add( "foo", Strings.getUUID( 0L ) );
+        idx.add( "foo", Strings.getUUID( 1L ) );
+        idx.add( "bar", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "bar" ) );
+
+        idx.drop( "foo", Strings.getUUID( 0L ) );
+        idx.drop( "bar", Strings.getUUID( 0L ) );
+        assertFalse( idx.forward( "bar", Strings.getUUID( 0L ) ) );
+        assertFalse( idx.forward( "foo", Strings.getUUID( 0L ) ) );
+
+        idx.drop( "bar", Strings.getUUID( 1L ) );
+        idx.drop( "foo", Strings.getUUID( 1L ) );
+        assertNull( idx.forwardLookup( "foo" ) );
+        assertNull( idx.forwardLookup( "bar" ) );
+        assertEquals( 0, idx.count() );
+    }
+
+
+    @Test
+    public void testAddDropOneByOne() throws Exception
+    {
+        initIndex();
+        assertNull( idx.forwardLookup( "foo" ) );
+        assertNull( idx.forwardLookup( "bar" ) );
+
+        // test add/drop without adding any duplicates
+        idx.add( "foo", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+
+        idx.drop( "foo", Strings.getUUID( 0L ) );
+        assertNull( idx.forwardLookup( "foo" ) );
+
+        // test add/drop with duplicates but one at a time
+        idx.add( "foo", Strings.getUUID( 0L ) );
+        idx.add( "foo", Strings.getUUID( 1L ) );
+        idx.add( "bar", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "bar" ) );
+
+        idx.drop( "bar", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( "foo" ) );
+        assertFalse( idx.forward( "bar", Strings.getUUID( 0L ) ) );
+
+        idx.drop( "foo", Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 1L ), idx.forwardLookup( "foo" ) );
+        assertFalse( idx.forward( "foo", Strings.getUUID( 0L ) ) );
+
+        idx.drop( "foo", Strings.getUUID( 1L ) );
+        assertNull( idx.forwardLookup( "foo" ) );
+        assertNull( idx.forwardLookup( "bar" ) );
+        assertEquals( 0, idx.count() );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Miscellaneous Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testCursors() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.count() );
+
+        idx.add( "foo", Strings.getUUID( 1234L ) );
+        assertEquals( 1, idx.count() );
+
+        idx.add( "foo", Strings.getUUID( 333L ) );
+        assertEquals( 2, idx.count() );
+
+        idx.add( "bar", Strings.getUUID( 555L ) );
+        assertEquals( 3, idx.count() );
+
+        // use forward index's cursor
+        Cursor<IndexEntry<String, String>> cursor = idx.forwardCursor();
+        cursor.beforeFirst();
+
+        assertEquals( 3, idx.count() );
+
+        cursor.next();
+        IndexEntry<String, String> e1 = cursor.get();
+        assertEquals( Strings.getUUID( 555L ), e1.getId() );
+        assertEquals( "bar", e1.getKey() );
+
+        cursor.next();
+        IndexEntry<String, String> e2 = cursor.get();
+        assertEquals( Strings.getUUID( 333L ), e2.getId() );
+        assertEquals( "foo", e2.getKey() );
+
+        cursor.next();
+        IndexEntry<String, String> e3 = cursor.get();
+        assertEquals( Strings.getUUID( 1234L ), e3.getId() );
+        assertEquals( "foo", e3.getKey() );
+
+        cursor.close();
+    }
+
+
+    @Test
+    public void testNoEqualityMatching() throws Exception
+    {
+        MavibotIndex<Object, Object> MavibotIndex = new MavibotIndex<Object, Object>( recordMan, "1.1", false );
+
+        try
+        {
+            AttributeType noEqMatchAttribute = new AttributeType( "1.1" );
+            MavibotIndex.setWkDirPath( dbFileDir.toURI() );
+            MavibotIndex.init( schemaManager, noEqMatchAttribute );
+            fail( "should not get here" );
+        }
+        catch ( IOException e )
+        {
+        }
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Failing Tests
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testSingleValuedAttribute() throws Exception
+    {
+        MavibotIndex<Object, Object> MavibotIndex = new MavibotIndex<Object, Object>( recordMan, SchemaConstants.CREATORS_NAME_AT, false );
+        MavibotIndex.setWkDirPath( dbFileDir.toURI() );
+        MavibotIndex.init( schemaManager, schemaManager.lookupAttributeTypeRegistry( SchemaConstants.CREATORS_NAME_AT ) );
+        MavibotIndex.close();
+    }
+}

Added: directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotMasterTableTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotMasterTableTest.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotMasterTableTest.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotMasterTableTest.java Tue May 14 03:09:53 2013
@@ -0,0 +1,125 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaloader.LdifSchemaLoader;
+import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.api.util.exception.Exceptions;
+import org.apache.mavibot.btree.RecordManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test cases for MavibotMasterTable.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotMasterTableTest
+{
+    private static final Logger LOG = LoggerFactory.getLogger( MavibotMasterTableTest.class );
+
+    private MavibotMasterTable table;
+    
+    private static SchemaManager schemaManager = null;
+
+    private RecordManager recordMan;
+
+    @Rule
+    public TemporaryFolder tmpDir = new TemporaryFolder();
+    
+    @BeforeClass
+    public static void loadSchema() throws Exception
+    {
+        String workingDirectory = System.getProperty( "workingDirectory" );
+
+        if ( workingDirectory == null )
+        {
+            String path = MavibotMasterTableTest.class.getResource( "" ).getPath();
+            int targetPos = path.indexOf( "target" );
+            workingDirectory = path.substring( 0, targetPos + 6 );
+        }
+
+        File schemaRepository = new File( workingDirectory, "schema" );
+        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+        extractor.extractOrCopy( true );
+        LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
+
+        schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabled();
+
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+        
+        MavibotEntrySerializer.setSchemaManager( schemaManager );
+    }
+
+
+    @Before
+    public void createTable() throws Exception
+    {
+        destroyTable();
+
+        recordMan = new RecordManager( tmpDir.getRoot().getAbsolutePath() );
+        
+        table = new MavibotMasterTable( recordMan, schemaManager, "master" );
+        LOG.debug( "Created new table and populated it with data" );
+    }
+
+
+    @After
+    public void destroyTable() throws Exception
+    {
+        if( table == null )
+        {
+            return;
+        }
+        
+        table.close();
+    }
+
+
+    @Test
+    public void testAll() throws Exception
+    {
+        assertNull( table.get( Strings.getUUID( 0L ) ) );
+        assertEquals( 0, table.count() );
+    }
+}

Added: directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndexTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndexTest.java?rev=1482179&view=auto
==============================================================================
--- directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndexTest.java (added)
+++ directory/apacheds/trunk/mavibot-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/mavibot/MavibotRdnIndexTest.java Tue May 14 03:09:53 2013
@@ -0,0 +1,346 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition.impl.btree.mavibot;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.directory.api.ldap.model.cursor.Cursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.name.Rdn;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.api.ldap.schemaloader.LdifSchemaLoader;
+import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.api.util.exception.Exceptions;
+import org.apache.directory.server.constants.ApacheSchemaConstants;
+import org.apache.directory.server.xdbm.Index;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.ParentIdAndRdn;
+import org.apache.mavibot.btree.RecordManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * Tests the MavibotRdnIndex.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class MavibotRdnIndexTest
+{
+    private Index<ParentIdAndRdn, Entry, String> idx;
+    
+    private static SchemaManager schemaManager;
+
+    private RecordManager recordMan;
+
+    @Rule
+    public TemporaryFolder tmpDir = new TemporaryFolder();
+    
+    @BeforeClass
+    public static void init() throws Exception
+    {
+        String workingDirectory = System.getProperty( "workingDirectory" );
+
+        if ( workingDirectory == null )
+        {
+            String path = MavibotRdnIndexTest.class.getResource( "" ).getPath();
+            int targetPos = path.indexOf( "target" );
+            workingDirectory = path.substring( 0, targetPos + 6 );
+        }
+
+        File schemaRepository = new File( workingDirectory, "schema" );
+        SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+        extractor.extractOrCopy( true );
+        LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
+        schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabled();
+
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+    }
+
+
+    @Before
+    public void setup() throws IOException
+    {
+        recordMan = new RecordManager( tmpDir.getRoot().getAbsolutePath() );
+    }
+
+
+    @After
+    public void teardown() throws Exception
+    {
+        destroyIndex();
+        recordMan.close();
+    }
+
+
+    void destroyIndex() throws Exception
+    {
+        if ( idx != null )
+        {
+            idx.sync();
+            idx.close();
+        }
+
+        idx = null;
+    }
+
+
+    void initIndex() throws Exception
+    {
+        MavibotRdnIndex index = new MavibotRdnIndex( recordMan );
+        index.setWkDirPath( tmpDir.getRoot().toURI() );
+        initIndex( index );
+    }
+
+
+    void initIndex( MavibotRdnIndex jdbmIdx ) throws Exception
+    {
+        if ( jdbmIdx == null )
+        {
+            jdbmIdx = new MavibotRdnIndex( recordMan );
+        }
+
+        jdbmIdx.init( schemaManager,
+            schemaManager.lookupAttributeTypeRegistry( ApacheSchemaConstants.APACHE_RDN_AT_OID ) );
+        this.idx = jdbmIdx;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Property Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testCacheSize() throws Exception
+    {
+        // uninitialized index
+        MavibotRdnIndex MavibotRdnIndex = new MavibotRdnIndex( recordMan );
+        MavibotRdnIndex.setCacheSize( 337 );
+        assertEquals( 337, MavibotRdnIndex.getCacheSize() );
+
+        // initialized index
+        initIndex();
+        try
+        {
+            idx.setCacheSize( 30 );
+            fail( "Should not be able to set cacheSize after initialization." );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        destroyIndex();
+        initIndex();
+
+        assertEquals( Index.DEFAULT_INDEX_CACHE_SIZE, idx.getCacheSize() );
+    }
+
+
+    @Test
+    public void testGetAttribute() throws Exception
+    {
+        // uninitialized index
+        MavibotRdnIndex rdnIndex = new MavibotRdnIndex( recordMan );
+        assertNull( rdnIndex.getAttribute() );
+
+        initIndex();
+        assertEquals( schemaManager.lookupAttributeTypeRegistry( ApacheSchemaConstants.APACHE_RDN_AT ),
+            idx.getAttribute() );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Count Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testCount() throws Exception
+    {
+        initIndex();
+        assertEquals( 0, idx.count() );
+
+        ParentIdAndRdn key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( "cn=key" ) );
+
+        idx.add( key, Strings.getUUID( 0L ) );
+        assertEquals( 1, idx.count() );
+
+        // setting a different parentId should make this key a different key
+        key = new ParentIdAndRdn( Strings.getUUID( 1L ), new Rdn( "cn=key" ) );
+
+        idx.add( key, Strings.getUUID( 1L ) );
+        assertEquals( 2, idx.count() );
+
+        //count shouldn't get affected cause of inserting the same key
+        idx.add( key, Strings.getUUID( 2L ) );
+        assertEquals( 2, idx.count() );
+
+        key = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( "cn=key" ) );
+        idx.add( key, Strings.getUUID( 3L ) );
+        assertEquals( 3, idx.count() );
+    }
+
+
+    @Test
+    public void testCountOneArg() throws Exception
+    {
+        initIndex();
+
+        ParentIdAndRdn key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( "cn=key" ) );
+
+        assertEquals( 0, idx.count( key ) );
+
+        idx.add( key, Strings.getUUID( 0L ) );
+        assertEquals( 1, idx.count( key ) );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Add, Drop and Lookup Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testLookups() throws Exception
+    {
+        initIndex();
+
+        ParentIdAndRdn key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( schemaManager, "cn=key" ) );
+
+        assertNull( idx.forwardLookup( key ) );
+
+        idx.add( key, Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( key ) );
+        assertEquals( key, idx.reverseLookup( Strings.getUUID( 0L ) ) );
+
+        // check with the different case in UP name, this ensures that the custom
+        // key comparator is used
+        key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( schemaManager, "cn=KEY" ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( key ) );
+        assertEquals( key, idx.reverseLookup( Strings.getUUID( 0L ) ) );
+    }
+
+
+    @Test
+    public void testAddDropById() throws Exception
+    {
+        initIndex();
+
+        ParentIdAndRdn key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( "cn=key" ) );
+
+        assertNull( idx.forwardLookup( key ) );
+
+        // test add/drop without adding any duplicates
+        idx.add( key, Strings.getUUID( 0L ) );
+        assertEquals( Strings.getUUID( 0L ), idx.forwardLookup( key ) );
+
+        idx.drop( key, Strings.getUUID( 0L ) );
+        assertNull( idx.forwardLookup( key ) );
+        assertNull( idx.reverseLookup( Strings.getUUID( 0L ) ) );
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Miscellaneous Test Methods
+    // -----------------------------------------------------------------------
+
+    @Test
+    public void testCursors() throws Exception
+    {
+        initIndex();
+
+        ParentIdAndRdn key = new ParentIdAndRdn( Strings.getUUID( 0L ), new Rdn( "cn=key" ) );
+
+        assertEquals( 0, idx.count() );
+
+        idx.add( key, Strings.getUUID( 0L ) );
+        assertEquals( 1, idx.count() );
+
+        for ( long i = 1; i < 5; i++ )
+        {
+            key = new ParentIdAndRdn( Strings.getUUID( i ), new Rdn( "cn=key" + i ) );
+
+            idx.add( key, Strings.getUUID( i ) );
+        }
+
+        assertEquals( 5, idx.count() );
+
+        // use forward index's cursor
+        Cursor<IndexEntry<ParentIdAndRdn, String>> cursor = idx.forwardCursor();
+        cursor.beforeFirst();
+
+        cursor.next();
+        IndexEntry<ParentIdAndRdn, String> e1 = cursor.get();
+        assertEquals( Strings.getUUID( 0L ), e1.getId() );
+        assertEquals( "cn=key", e1.getKey().getRdns()[0].getName() );
+        assertEquals( Strings.getUUID( 0L ), e1.getKey().getParentId() );
+
+        cursor.next();
+        IndexEntry<ParentIdAndRdn, String> e2 = cursor.get();
+        assertEquals( Strings.getUUID( 1L ), e2.getId() );
+        assertEquals( "cn=key1", e2.getKey().getRdns()[0].getName() );
+        assertEquals( Strings.getUUID( 1L ), e2.getKey().getParentId() );
+
+        cursor.next();
+        IndexEntry<ParentIdAndRdn, String> e3 = cursor.get();
+        assertEquals( Strings.getUUID( 2L ), e3.getId() );
+        assertEquals( "cn=key2", e3.getKey().getRdns()[0].getName() );
+        assertEquals( Strings.getUUID( 2 ), e3.getKey().getParentId() );
+
+        
+        // test before(Tuple<>)
+        cursor.before( e3 );
+        // e3
+        assertTrue( cursor.next() );
+        assertEquals( e3.getId(), cursor.get().getId() );
+
+        // e4
+        assertTrue( cursor.next() );
+        assertEquals( Strings.getUUID( 3 ), cursor.get().getId() );
+
+        // e5
+        assertTrue( cursor.next() );
+        assertEquals( Strings.getUUID( 4 ), cursor.get().getId() );
+
+        assertFalse( cursor.next() );
+        
+        cursor.close();
+    }
+
+    
+}



Mime
View raw message