You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/07/19 22:18:27 UTC

svn commit: r423587 - in /directory/branches/apacheds/optimization/core/src: main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/ test/java/org/apache/directory/server/core/partition/ test/java/org/apache/directory/server/core/partitio...

Author: akarasulu
Date: Wed Jul 19 13:18:26 2006
New Revision: 423587

URL: http://svn.apache.org/viewvc?rev=423587&view=rev
Log:
Added some JDBM serializers so we can optimize performance by replacing Java
Serialization with custom fast serialization.  More to come ...

Added:
    directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializer.java
    directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributesSerializer.java
    directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BigIntegerSerializer.java
    directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializer.java
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializerTest.java
    directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializerTest.java
Modified:
    directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java

Added: directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializer.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializer.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializer.java (added)
+++ directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializer.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,428 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+
+import org.apache.directory.shared.ldap.message.LockableAttributeImpl;
+
+import jdbm.helper.Serializer;
+
+
+/**
+ * Serializes a attributes object using a custom serialization mechanism
+ * so we do not have to rely on Java Serialization which is much more 
+ * costly.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributeSerializer implements Serializer
+{
+    private static final long serialVersionUID = -3756830073760754086L;
+  
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    /** value for type parameter for string (non-binary) attributes */
+    private static final byte STRING_TYPE = 0x00;
+    /** value for type parameter for byte array (binary) attributes */
+    private static final byte BYTE_ARRAY_TYPE = 0x01;
+    
+
+    // -----------------------------------------------------------------------
+    // Methods for deserialization
+    // -----------------------------------------------------------------------
+    
+    
+    /**
+     * Deserializes an attribute from the custom serialization structure.
+     * 
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public Object deserialize( byte[] buf ) throws IOException
+    {
+        String id = readString( buf );
+        LockableAttributeImpl attr = new LockableAttributeImpl( id );
+        int pos = ( id.length() << 1 ) + 4;
+        
+        // read the type of the objects stored in this attribute
+        if ( buf[pos] == STRING_TYPE )
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                String value = readString( buf, pos );
+                pos += ( value.length() << 1 ) + 4;
+                attr.add( value );
+            }
+        }
+        else
+        {
+            pos++;
+            while ( pos < buf.length )
+            {
+                byte[] value = readBytes( buf, pos );
+                pos += value.length + 4;
+                attr.add( value );
+            }
+        }
+        
+        return attr;
+    }
+
+    
+    /**
+     * Reads a String and it's length bytes from a buffer starting at 
+     * position 0.
+     * 
+     * @param buf the buffer to read the length and character bytes from
+     * @return the String contained at the start of the buffer
+     */
+    String readString( byte[] buf )
+    {
+        int length = getLength( buf );
+        
+        if ( length == 0 )
+        {
+            return "";
+        }
+
+        // create the new char buffer
+        char[] strchars = new char[length>>1];
+        
+        int ch = 0;
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++ )
+        {
+            jj = ( ii << 1 ) + 4;
+            ch = buf[jj] << 8 & 0x0000FF00;
+            ch |= buf[jj+1] & 0x000000FF;
+            strchars[ii] = ( char ) ch;
+        }
+
+        return new String( strchars );
+    }
+    
+    
+    /**
+     * Reads a String and it's length bytes from a buffer starting at 
+     * a specific offset.
+     * 
+     * @param buf the buffer to read the length and character bytes from
+     * @param offset the offset into the buffer to start reading from
+     * @return the String contained at the offset in the buffer
+     */
+    String readString( byte[] buf, int offset )
+    {
+        int length = getLength( buf, offset );
+        
+        if ( length == 0 )
+        {
+            return "";
+        }
+
+        // create the new char buffer
+        char[] strchars = new char[length>>1];
+        
+        int ch = 0;
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++ )
+        {
+            jj = ( ii << 1 ) + 4 + offset;
+            ch = buf[jj] << 8 & 0x0000FF00;
+            ch |= buf[jj+1] & 0x000000FF;
+            strchars[ii] = ( char ) ch;
+        }
+
+        return new String( strchars );
+    }
+    
+    
+    /**
+     * Reads a byte array from a buffer including its length starting
+     * from an offset in the buffer.
+     * 
+     * @param buf the buffer to read the byte array from
+     * @param offset the offset to start reading from starting with 4-byte length
+     * @return the byte array contained in the buffer
+     */
+    byte[] readBytes( byte[] buf, int offset )
+    {
+        int length = getLength( buf, offset );
+        
+        if ( length == 0 )
+        {
+            return EMPTY_BYTE_ARRAY;
+        }
+
+        byte[] bites = new byte[length];
+        System.arraycopy( buf, offset+4, bites, 0, length );
+        return bites;
+    }
+
+    
+    // -----------------------------------------------------------------------
+    // Methods for serialization
+    // -----------------------------------------------------------------------
+    
+    
+    /**
+     * Serializes an attribute using the following structure:
+     * <code>
+     *   [id-length][id-bytes][is-binary][length0][value0]...[lengthN][valueN]
+     * </code>
+     * 
+     * Here the id-length is the 4 byte int value of the length of bytes
+     * for the id string bytes.  The id-bytes are the bytes for the id string.
+     * The is-binary byte is a true or false for whether or not the values 
+     * are byte[] or String types.  Following this is an array of length-value 
+     * tuples for the values of the Attributes.  
+     * 
+     */
+    public byte[] serialize( Object obj ) throws IOException
+    {
+        Attribute attr = ( Attribute ) obj;
+        
+        // calculate the size of the entire byte[] and allocate
+        byte[] buf = new byte[calculateSize( attr )];
+        
+        // write the length of the id and it's value
+        int pos = write( buf, attr.getID() );
+        
+        try
+        {
+            // write the type or is-binary field
+            Object first = attr.get();
+            if ( first instanceof String )
+            {
+                buf[pos] = STRING_TYPE;
+                pos++;
+
+                // write out each value to the buffer whatever type it may be
+                for ( NamingEnumeration ii = attr.getAll(); ii.hasMore(); /**/ )
+                {
+                    String value = ( String ) ii.next();
+                    pos = write( buf, value, pos );
+                }
+            }
+            else
+            {
+                buf[pos] = BYTE_ARRAY_TYPE;
+                pos++;
+
+                // write out each value to the buffer whatever type it may be
+                for ( NamingEnumeration ii = attr.getAll(); ii.hasMore(); /**/ )
+                {
+                    byte[] value = ( byte[] ) ii.next();
+                    pos = write( buf, value, pos );
+                }
+            }
+
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing attribute values." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+        
+        
+        return buf;
+    }
+    
+    
+    int calculateSize( Attribute attr ) throws IOException
+    {
+        int size = 4; // start with first length for attribute id
+        size += attr.getID().length() << 1; // the length of id * 2 added
+        size++; // add one for the type
+        
+        try
+        {
+            for ( NamingEnumeration ii = attr.getAll(); ii.hasMore(); /**/ )
+            {
+                Object value = ii.next();
+                if ( value instanceof String )
+                {
+                    size += ( ( String ) value ).length() << 1; // length of sting * 2
+                }
+                else 
+                {
+                    size += ( ( byte [] ) value ).length; // no need to multiply byte[]s
+                }
+                
+                size += 4; // add 4 bytes for a length 
+            }
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing attribute values." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+        
+        return size;
+    }
+    
+    
+    byte[] getLengthBytes( String str )
+    {
+        return getLengthBytes( str.length() << 1 );
+    }
+    
+    
+    byte[] getLengthBytes( byte[] bites )
+    {
+        return getLengthBytes( bites.length );
+    }
+
+    
+    byte[] getLengthBytes( int length )
+    {
+        byte[] lengthBytes = new byte[4];
+
+        lengthBytes[0] = ( byte ) ( length >> 24 & 0x000000FF );
+        lengthBytes[1] = ( byte ) ( length >> 16 & 0x000000FF );
+        lengthBytes[2] = ( byte ) ( length >> 8 & 0x000000FF );
+        lengthBytes[3] = ( byte ) ( length & 0x000000FF );
+        
+        return lengthBytes;
+    }
+
+    
+    int getLength( byte[] bites )
+    {
+        int length  = bites[0] << 24 & 0xFF000000;
+        length     |= bites[1] << 16 & 0x00FF0000;
+        length     |= bites[2] <<  8 & 0x0000FF00;
+        length     |= bites[3]       & 0x000000FF;
+        
+        return length;
+    }
+
+    
+    int getLength( byte[] bites, int offset )
+    {
+        int length  = bites[offset]   << 24 & 0xFF000000;
+        length     |= bites[offset+1] << 16 & 0x00FF0000;
+        length     |= bites[offset+2] <<  8 & 0x0000FF00;
+        length     |= bites[offset+3]       & 0x000000FF;
+        
+        return length;
+    }
+
+    
+    int write( byte[] buf, String value )
+    {
+        int pos = writeLengthBytes( buf, value.length() << 1 );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    int write( byte[] buf, byte[] value )
+    {
+        int pos = writeLengthBytes( buf, value.length );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    int write( byte[] buf, String value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length() << 1, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    int write( byte[] buf, byte[] value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    int writeValueBytes( byte[] buf, String value )
+    {
+        if ( ( ( String ) value ).length() == 0 )
+        {
+            return 0;
+        }
+        
+        char[] strchars = ( ( String ) value ).toCharArray();
+        int jj = 0;
+        for ( int ii = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            buf[jj] = ( byte ) ( strchars[ii] >> 8 & 0x00FF );
+            buf[jj+1] = ( byte ) ( strchars[ii] & 0x00FF );
+        }
+        return jj+2;
+    }
+
+    
+    int writeValueBytes( byte[] buf, String value, int offset )
+    {
+        if ( ( ( String ) value ).length() == 0 )
+        {
+            return offset;
+        }
+        
+        char[] strchars = ( ( String ) value ).toCharArray();
+        int jj = 0;
+        for ( int ii = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            buf[jj+offset] = ( byte ) ( strchars[ii] >> 8 & 0x00FF );
+            buf[jj+offset+1] = ( byte ) ( strchars[ii] & 0x00FF );
+        }
+        return jj+offset;
+    }
+
+    
+    int writeValueBytes( byte[] buf, byte[] value, int offset )
+    {
+        if ( value.length == 0 )
+        {
+            return offset;
+        }
+
+        System.arraycopy( value, 0, buf, offset, value.length );
+        return offset + value.length;
+    }
+
+    
+    int writeLengthBytes( byte[] buf, int length )
+    {
+        buf[0] = ( byte ) ( length >> 24 & 0x000000FF );
+        buf[1] = ( byte ) ( length >> 16 & 0x000000FF );
+        buf[2] = ( byte ) ( length >> 8 & 0x000000FF );
+        buf[3] = ( byte ) ( length & 0x000000FF );
+        return 4;
+    }
+    
+    
+    int writeLengthBytes( byte[] buf, int length, int offset )
+    {
+        buf[0+offset] = ( byte ) ( length >> 24 & 0x000000FF );
+        buf[1+offset] = ( byte ) ( length >> 16 & 0x000000FF );
+        buf[2+offset] = ( byte ) ( length >> 8 & 0x000000FF );
+        buf[3+offset] = ( byte ) ( length & 0x000000FF );
+        return offset+4;
+    }
+}

Added: directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributesSerializer.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributesSerializer.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributesSerializer.java (added)
+++ directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributesSerializer.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,52 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+import java.io.IOException;
+
+import jdbm.helper.Serializer;
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributesSerializer implements Serializer
+{
+    private static final long serialVersionUID = -3756830073760754086L;
+
+
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public Object deserialize( byte[] arg0 ) throws IOException
+    {
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#serialize(java.lang.Object)
+     */
+    public byte[] serialize( Object arg0 ) throws IOException
+    {
+        return null;
+    }
+
+}

Added: directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BigIntegerSerializer.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BigIntegerSerializer.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BigIntegerSerializer.java (added)
+++ directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BigIntegerSerializer.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,55 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import jdbm.helper.Serializer;
+
+
+/**
+ * A custom BigInteger serializer to [de]serialize BigIntegers.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class BigIntegerSerializer implements Serializer
+{
+    private static final long serialVersionUID = 6768192848157685880L;
+
+
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public Object deserialize( byte[] bigIntBytes ) throws IOException
+    {
+        return new BigInteger( bigIntBytes );
+    }
+
+
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#serialize(java.lang.Object)
+     */
+    public byte[] serialize( Object bigInt ) throws IOException
+    {
+        return ( ( BigInteger ) bigInt ).toByteArray();
+    }
+}

Modified: directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java?rev=423587&r1=423586&r2=423587&view=diff
==============================================================================
--- directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java (original)
+++ directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java Wed Jul 19 13:18:26 2006
@@ -87,7 +87,7 @@
      * @param comparator a tuple comparator
      * @throws NamingException if the table's file cannot be created
      */
-    public JdbmTable(String name, boolean allowsDuplicates, RecordManager manager, TupleComparator comparator)
+    public JdbmTable( String name, boolean allowsDuplicates, RecordManager manager, TupleComparator comparator )
         throws NamingException
     {
         this.name = name;
@@ -148,7 +148,7 @@
      * @param keyComparator a tuple comparator
      * @throws NamingException if the table's file cannot be created
      */
-    public JdbmTable(String name, RecordManager manager, SerializableComparator keyComparator) throws NamingException
+    public JdbmTable( String name, RecordManager manager, SerializableComparator keyComparator ) throws NamingException
     {
         this( name, false, manager, new KeyOnlyComparator( keyComparator ) );
     }

Added: directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializer.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializer.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializer.java (added)
+++ directory/branches/apacheds/optimization/core/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializer.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,81 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+
+import java.io.IOException;
+
+import jdbm.helper.Serializer;
+
+
+/**
+ * A custom String serializer to [de]serialize Strings.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StringSerializer implements Serializer
+{
+    private static final long serialVersionUID = -173163945773783649L;
+
+
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public Object deserialize( byte[] bites ) throws IOException
+    {
+        if ( bites.length == 0 )
+        {
+            return "";
+        }
+
+        char[] strchars = new char[bites.length >> 1];
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            int ch = bites[jj] << 8 & 0x0000FF00;
+            ch |= bites[jj+1] & 0x000000FF;
+            strchars[ii] = ( char ) ch;
+        }
+        return new String( strchars );
+    }
+
+
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    
+    /* (non-Javadoc)
+     * @see jdbm.helper.Serializer#serialize(java.lang.Object)
+     */
+    public byte[] serialize( Object str ) throws IOException
+    {
+        if ( ( ( String ) str ).length() == 0 )
+        {
+            return EMPTY_BYTE_ARRAY;
+        }
+        
+        char[] strchars = ( ( String ) str ).toCharArray();
+        byte[] bites = new byte[strchars.length<<1];
+        for ( int ii = 0, jj = 0; ii < strchars.length; ii++, jj = ii << 1 )
+        {
+            bites[jj] = ( byte ) ( strchars[ii] >> 8 & 0x00FF );
+            bites[jj+1] = ( byte ) ( strchars[ii] & 0x00FF );
+        }
+        
+        return bites;
+    }
+}

Added: directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializerTest.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializerTest.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializerTest.java (added)
+++ directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/AttributeSerializerTest.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,251 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+
+import org.apache.directory.shared.ldap.message.LockableAttributeImpl;
+import org.apache.directory.shared.ldap.util.ArrayUtils;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests the {@link AttributeSerializer}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributeSerializerTest extends TestCase
+{
+    public void testGetLengthBytes()
+    {
+        AttributeSerializer serializer = new AttributeSerializer();
+        
+        // test first 10 values
+        for ( int ii = 0; ii < 10; ii++ )
+        {
+            byte[] bites = serializer.getLengthBytes( ii );
+            int deserialized = serializer.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test first byte boundry
+        for ( int ii = 250; ii < 260; ii++ )
+        {
+            byte[] bites = serializer.getLengthBytes( ii );
+            int deserialized = serializer.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test 2nd byte boundry
+        for ( int ii = 65530; ii < 65540; ii++ )
+        {
+            byte[] bites = serializer.getLengthBytes( ii );
+            int deserialized = serializer.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test 3rd byte boundry
+        for ( int ii = 16777210; ii < 16777220; ii++ )
+        {
+            byte[] bites = serializer.getLengthBytes( ii );
+            int deserialized = serializer.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+    }
+    
+    
+    public void testWriteLengthBytes0()
+    {
+        AttributeSerializer serializer = new AttributeSerializer();
+        byte[] buf = new byte[7];
+        
+        int pos = serializer.writeLengthBytes( buf, 23 );
+        assertEquals( 4, pos );
+        assertEquals( 0, buf[0] );
+        assertEquals( 0, buf[1] );
+        assertEquals( 0, buf[2] );
+        assertEquals( 23, buf[3] );
+        assertEquals( 0, buf[4] );
+        assertEquals( 0, buf[5] );
+        assertEquals( 0, buf[6] );
+        
+        pos = serializer.writeValueBytes( buf, "a", pos );
+        assertEquals( 6, pos );
+        assertEquals( 0, buf[4] );
+        assertEquals( 97, buf[5] );
+        assertEquals( 0, buf[6] );
+    }
+
+
+    public void testWriteValueBytes0()
+    {
+        AttributeSerializer serializer = new AttributeSerializer();
+        byte[] buf = new byte[20];
+        
+        int pos = serializer.writeLengthBytes( buf, 23 );
+        assertEquals( 4, pos );
+        assertEquals( 0, buf[0] );
+        assertEquals( 0, buf[1] );
+        assertEquals( 0, buf[2] );
+        assertEquals( 23, buf[3] );
+        assertEquals( 0, buf[4] );
+        assertEquals( 0, buf[5] );
+        assertEquals( 0, buf[6] );
+        
+        pos = serializer.writeValueBytes( buf, "abc", pos );
+        assertEquals( 10,  pos );
+        assertEquals( 0,  buf[4] );
+        assertEquals( 97, buf[5] );
+        assertEquals( 0,  buf[6] );
+        assertEquals( 98, buf[7] );
+        assertEquals( 0,  buf[8] );
+        assertEquals( 99, buf[9] );
+        assertEquals( 0,  buf[10] ); // here now
+        assertEquals( 0,  buf[11] );
+        assertEquals( 0,  buf[12] );
+        
+        pos = serializer.write( buf, "def", pos );
+        assertEquals( 20, pos );
+        assertEquals( 0, buf[10] );
+        assertEquals( 0, buf[11] );
+        assertEquals( 0, buf[12] );
+        assertEquals( 6, buf[13] );
+        
+        assertEquals( 0,   buf[14] );
+        assertEquals( 100, buf[15] );
+        assertEquals( 0,   buf[16] );
+        assertEquals( 101, buf[17] );
+        assertEquals( 0,   buf[18] );
+        assertEquals( 102, buf[19] );
+    }
+    
+    
+    public void testReadString()
+    {
+        AttributeSerializer serializer = new AttributeSerializer();
+        byte[] buf = new byte[26];
+        
+        // let's write the length so we can read it
+        int pos = serializer.writeLengthBytes( buf, 6 );
+        assertEquals( 4, pos );
+        assertEquals( 0, buf[0] );
+        assertEquals( 0, buf[1] );
+        assertEquals( 0, buf[2] );
+        assertEquals( 6, buf[3] );
+        
+        // let's write the value so we can read it
+        pos = serializer.writeValueBytes( buf, "abc", pos );
+        assertEquals( 10,  pos );
+        assertEquals( 0,  buf[4] );
+        assertEquals( 97, buf[5] );
+        assertEquals( 0,  buf[6] );
+        assertEquals( 98, buf[7] );
+        assertEquals( 0,  buf[8] );
+        assertEquals( 99, buf[9] );
+
+        // let's write another string as well
+        pos = serializer.write( buf, "defgh", pos );
+        assertEquals( 24, pos );
+        assertEquals( 0, buf[10] );
+        assertEquals( 0, buf[11] );
+        assertEquals( 0, buf[12] );
+        assertEquals( 10, buf[13] );
+        
+        assertEquals( 0,   buf[14] );
+        assertEquals( 100, buf[15] );
+        assertEquals( 0,   buf[16] );
+        assertEquals( 101, buf[17] );
+        assertEquals( 0,   buf[18] );
+        assertEquals( 102, buf[19] );
+        assertEquals( 0,   buf[20] );
+        assertEquals( 103, buf[21] );
+        assertEquals( 0,   buf[22] );
+        assertEquals( 104, buf[23] );
+        assertEquals( 0,   buf[24] );
+        assertEquals( 0,   buf[25] );
+        
+        // now let's read "abc"
+        String s1 = serializer.readString( buf );
+        assertEquals( "abc", s1 );
+    }
+    
+    
+    public void testFullCycleNonBinaryAttribute() throws IOException
+    {
+        LockableAttributeImpl attr = new LockableAttributeImpl( "testing" );
+        AttributeSerializer serializer = new AttributeSerializer();
+        attr.add( "value0" );
+        attr.add( "val1" );
+        attr.add( "anything over here!" );
+        
+        byte[] serialized = serializer.serialize( attr );
+        Attribute deserialized = ( Attribute ) serializer.deserialize( serialized );
+        assertEquals( attr, deserialized );
+    }
+
+
+    
+    
+    public void testFullCycleBinaryAttribute() throws IOException, NamingException
+    {
+        LockableAttributeImpl attr = new LockableAttributeImpl( "testing" );
+        AttributeSerializer serializer = new AttributeSerializer();
+        byte[] ba0 = new byte[2];
+        ba0[0] = 7;
+        ba0[1] = 23;
+        attr.add( ba0 );
+        byte[] ba1 = new byte[3];
+        ba1[0] = 34;
+        ba1[1] = 111;
+        ba1[2] = 67;
+        attr.add( ba1 );
+        
+        byte[] serialized = serializer.serialize( attr );
+        Attribute deserialized = ( Attribute ) serializer.deserialize( serialized );
+        ArrayUtils.isEquals( ba0, ( byte[] ) deserialized.get() );
+        ArrayUtils.isEquals( ba1, ( byte[] ) deserialized.get( 1 ) );
+    }
+    
+    
+    public void doSerializerSpeedTest() throws IOException
+    {
+        final int limit = 1000000;
+        long start = System.currentTimeMillis();
+        for ( int ii = 0; ii < limit; ii++ )
+        {
+            LockableAttributeImpl attr = new LockableAttributeImpl( "testing" );
+            AttributeSerializer serializer = new AttributeSerializer();
+            attr.add( "value0" );
+            attr.add( "val1" );
+            attr.add( "anything over here!" );
+            
+            byte[] serialized = serializer.serialize( attr );
+            serializer.deserialize( serialized );
+        }
+        
+        System.out.println( limit + " attributes with 3 values each were serialized and deserialized in " 
+            + ( System.currentTimeMillis() - start ) + " (ms)" );
+    }
+}

Added: directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializerTest.java
URL: http://svn.apache.org/viewvc/directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializerTest.java?rev=423587&view=auto
==============================================================================
--- directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializerTest.java (added)
+++ directory/branches/apacheds/optimization/core/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/StringSerializerTest.java Wed Jul 19 13:18:26 2006
@@ -0,0 +1,73 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.jdbm;
+
+import java.io.IOException;
+
+import org.apache.commons.lang.RandomStringUtils;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StringSerializerTest extends TestCase
+{
+    public void testRandom() throws IOException
+    {
+        StringSerializer serializer = new StringSerializer();
+        for ( int ii = 0; ii < 100; ii++ )
+        {
+            String str = RandomStringUtils.random( ii );
+            byte [] serialized = serializer.serialize( str );
+            String deserialized = ( String ) serializer.deserialize( serialized );
+            assertEquals( str, deserialized );
+        }
+    }
+    
+    
+    char getChar( byte[] bites )
+    {
+        int ch = bites[0] << 8 & 0x0000FF00;
+        ch |= bites[1] & 0x000000FF;
+        return ( char ) ch;
+    }
+    
+    
+    byte[] getBytes( char ch )
+    {
+        byte[] bites = new byte[2];
+        bites[0] = ( byte ) ( ch >> 8 & 0x00FF );
+        bites[1] = ( byte ) ( ch & 0x00FF );
+        return bites;
+    }
+
+    
+    public void testConversion()
+    {
+        for ( char ch = 0; ch < 16383; ch++ )
+        {
+            byte[] bites = getBytes( ch );
+            char deserialized = getChar( bites );
+            assertEquals( ch, deserialized );
+        }
+    }
+}