directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r518705 - in /directory/shared/trunk/ldap/src: main/java/org/apache/directory/shared/ldap/util/ test/java/org/apache/directory/shared/ldap/util/
Date Thu, 15 Mar 2007 17:44:53 GMT
Author: elecharny
Date: Thu Mar 15 10:44:52 2007
New Revision: 518705

URL: http://svn.apache.org/viewvc?view=rev&rev=518705
Log:
Added the attribute(s)Serializer, used by the server to speedup the BTree operations

Added:
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtils.java
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributesSerializerUtils.java
    directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtilsTest.java

Added: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtils.java?view=auto&rev=518705
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtils.java
(added)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtils.java
Thu Mar 15 10:44:52 2007
@@ -0,0 +1,485 @@
+/*
+ *  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.shared.ldap.util;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+
+/**
+ * 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 AttributeSerializerUtils
+{
+    private static final long serialVersionUID = -3756830073760754086L;
+  
+    static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    /** value for type parameter for string (non-binary) attributes */
+    static final byte STRING_TYPE = 0x00;
+    /** value for type parameter for byte array (binary) attributes */
+    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 static final Object deserialize( byte[] buf ) throws IOException
+    {
+        String id = readString( buf );
+        AttributeImpl attr = new AttributeImpl( 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;
+    }
+
+    
+    /**
+     * Deserializes an attribute from the custom serialization structure.
+     * 
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public static final DeserializedAttribute deserialize( byte[] buf, int offset ) throws
IOException
+    {
+        final String id = readString( buf, offset );
+        final AttributeImpl attr = new AttributeImpl( id );
+        int pos = ( id.length() << 1 ) + 4 + offset;
+        
+        // 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 new DeserializedAttribute( attr, pos );
+    }
+
+    
+    final static class DeserializedAttribute 
+    {
+        private final int pos;
+        private final Attribute attr;
+        
+        private DeserializedAttribute( Attribute attr, int pos )
+        {
+            this.pos = pos;
+            this.attr = attr;
+        }
+
+        public int getPos()
+        {
+            return pos;
+        }
+
+        public Attribute getAttr()
+        {
+            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
+     */
+    static final 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
+     */
+    static final 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
+     */
+    static final 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 static final 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;
+    }
+    
+    
+    static final 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;
+    }
+    
+    
+    static final byte[] getLengthBytes( String str )
+    {
+        return getLengthBytes( str.length() << 1 );
+    }
+    
+    
+    static final byte[] getLengthBytes( byte[] bites )
+    {
+        return getLengthBytes( bites.length );
+    }
+
+    
+    static final 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;
+    }
+
+    
+    static final 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;
+    }
+
+    
+    static final 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;
+    }
+
+    
+    static final int write( byte[] buf, String value )
+    {
+        int pos = writeLengthBytes( buf, value.length() << 1 );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    static final int write( byte[] buf, byte[] value )
+    {
+        int pos = writeLengthBytes( buf, value.length );
+        return writeValueBytes( buf, value, pos );
+    }
+    
+
+    static final int write( byte[] buf, String value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length() << 1, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    static final int write( byte[] buf, byte[] value, int offset )
+    {
+        offset = writeLengthBytes( buf, value.length, offset );
+        return writeValueBytes( buf, value, offset );
+    }
+    
+
+    static final 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;
+    }
+
+    
+    static final 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;
+    }
+
+    
+    static final 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;
+    }
+
+    
+    static final 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;
+    }
+    
+    
+    static final 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/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributesSerializerUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributesSerializerUtils.java?view=auto&rev=518705
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributesSerializerUtils.java
(added)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/util/AttributesSerializerUtils.java
Thu Mar 15 10:44:52 2007
@@ -0,0 +1,188 @@
+/*
+ *  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.shared.ldap.util;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributesSerializerUtils
+{
+    private static final long serialVersionUID = -3756830073760754086L;
+    private static final byte SEPARATOR = -1;
+
+
+    /**
+     * @see jdbm.helper.Serializer#deserialize(byte[])
+     */
+    public static final Object deserialize( byte[] buf ) throws IOException
+    {
+        if ( buf.length == 0 )
+        {
+            return new AttributesImpl();
+        }
+
+        int pos = 0;
+        AttributesImpl attrs = new AttributesImpl();
+        while ( pos < buf.length )
+        {
+            String id = AttributeSerializerUtils.readString( buf, pos );
+            AttributeImpl attr = new AttributeImpl( id );
+            pos += ( id.length() << 1 ) + 4;
+
+            // read the type of the objects stored in this attribute
+            if ( buf[pos] == AttributeSerializerUtils.STRING_TYPE )
+            {
+                pos++;
+                while ( pos < buf.length && buf[pos] != SEPARATOR )
+                {
+                    String value = AttributeSerializerUtils.readString( buf, pos );
+                    pos += ( value.length() << 1 ) + 4;
+                    attr.add( value );
+                }
+            }
+            else
+            {
+                pos++;
+                while ( pos < buf.length && buf[pos] != SEPARATOR )
+                {
+                    byte[] value = AttributeSerializerUtils.readBytes( buf, pos );
+                    pos += value.length + 4;
+                    attr.add( value );
+                }
+            }
+
+            pos++; // skip the separator
+            attrs.put( attr );
+        }
+
+        return attrs;
+    }
+
+
+    /**
+     * @see jdbm.helper.Serializer#serialize(java.lang.Object)
+     */
+    public static final byte[] serialize( Object attrsObj ) throws IOException
+    {
+        Attributes attrs = ( Attributes ) attrsObj;
+
+        // calculate the size of the entire byte[] and allocate
+        byte[] buf = new byte[calculateSize( attrs )];
+        int pos = 0;
+        try
+        {
+            for ( NamingEnumeration ii = attrs.getAll(); ii.hasMore(); /**/)
+            {
+                // get an attribute at a time
+                Attribute attr = ( Attribute ) ii.next();
+
+                // write the length of the id and it's value
+                pos = AttributeSerializerUtils.write( buf, attr.getID(), pos );
+
+                // write the type or is-binary field
+                Object first = attr.get();
+                if ( first instanceof String )
+                {
+                    buf[pos] = AttributeSerializerUtils.STRING_TYPE;
+                    pos++;
+
+                    // write out each value to the buffer whatever type it may be
+                    for ( NamingEnumeration jj = attr.getAll(); jj.hasMore(); /**/)
+                    {
+                        String value = ( String ) jj.next();
+                        pos = AttributeSerializerUtils.write( buf, value, pos );
+                    }
+                }
+                else
+                {
+                    buf[pos] = AttributeSerializerUtils.BYTE_ARRAY_TYPE;
+                    pos++;
+
+                    // write out each value to the buffer whatever type it may be
+                    for ( NamingEnumeration jj = attr.getAll(); jj.hasMore(); /**/)
+                    {
+                        byte[] value = ( byte[] ) jj.next();
+                        pos = AttributeSerializerUtils.write( buf, value, pos );
+                    }
+                }
+                
+                if ( ii.hasMore() )
+                {
+                    buf[pos] = SEPARATOR;
+                    pos++;
+                }
+            }
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing attributes and/or
their values." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+
+        return buf;
+    }
+
+
+    private static final int calculateSize( Attributes attrs ) throws IOException
+    {
+        int size = 0;
+
+        try
+        {
+            for ( NamingEnumeration ii = attrs.getAll(); ii.hasMore(); /**/)
+            {
+                Attribute attr = ( Attribute ) ii.next();
+
+                if ( ii.hasMore() )
+                {
+                    // augment by attribute size and 1 for the separator
+                    size += AttributeSerializerUtils.calculateSize( attr ) + 1;
+                }
+                else
+                {
+                    // augment by attribute size only since there are no more attributes
left
+                    size += AttributeSerializerUtils.calculateSize( attr );
+                }
+            }
+        }
+        catch ( NamingException e )
+        {
+            IOException ioe = new IOException( "Failed while accesssing attributes." );
+            ioe.initCause( e );
+            throw ioe;
+        }
+
+        return size;
+    }
+}

Added: directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtilsTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtilsTest.java?view=auto&rev=518705
==============================================================================
--- directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtilsTest.java
(added)
+++ directory/shared/trunk/ldap/src/test/java/org/apache/directory/shared/ldap/util/AttributeSerializerUtilsTest.java
Thu Mar 15 10:44:52 2007
@@ -0,0 +1,246 @@
+/*
+ *  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.shared.ldap.util;
+
+
+import java.io.IOException;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.util.ArrayUtils;
+import org.apache.directory.shared.ldap.util.AttributeSerializerUtils;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests the {@link AttributeSerializerUtils}.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AttributeSerializerUtilsTest extends TestCase
+{
+    public void testGetLengthBytes()
+    {
+        // test first 10 values
+        for ( int ii = 0; ii < 10; ii++ )
+        {
+            byte[] bites = AttributeSerializerUtils.getLengthBytes( ii );
+            int deserialized = AttributeSerializerUtils.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test first byte boundry
+        for ( int ii = 250; ii < 260; ii++ )
+        {
+            byte[] bites = AttributeSerializerUtils.getLengthBytes( ii );
+            int deserialized = AttributeSerializerUtils.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test 2nd byte boundry
+        for ( int ii = 65530; ii < 65540; ii++ )
+        {
+            byte[] bites = AttributeSerializerUtils.getLengthBytes( ii );
+            int deserialized = AttributeSerializerUtils.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+
+        // test 3rd byte boundry
+        for ( int ii = 16777210; ii < 16777220; ii++ )
+        {
+            byte[] bites = AttributeSerializerUtils.getLengthBytes( ii );
+            int deserialized = AttributeSerializerUtils.getLength( bites );
+            assertEquals( ii, deserialized );
+        }
+    }
+    
+    
+    public void testWriteLengthBytes0()
+    {
+        byte[] buf = new byte[7];
+        
+        int pos = AttributeSerializerUtils.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 = AttributeSerializerUtils.writeValueBytes( buf, "a", pos );
+        assertEquals( 6, pos );
+        assertEquals( 0, buf[4] );
+        assertEquals( 97, buf[5] );
+        assertEquals( 0, buf[6] );
+    }
+
+
+    public void testWriteValueBytes0()
+    {
+        byte[] buf = new byte[20];
+        
+        int pos = AttributeSerializerUtils.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 = AttributeSerializerUtils.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 = AttributeSerializerUtils.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()
+    {
+        byte[] buf = new byte[26];
+        
+        // let's write the length so we can read it
+        int pos = AttributeSerializerUtils.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 = AttributeSerializerUtils.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 = AttributeSerializerUtils.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 = AttributeSerializerUtils.readString( buf );
+        assertEquals( "abc", s1 );
+    }
+    
+    
+    public void testFullCycleNonBinaryAttribute() throws IOException
+    {
+        AttributeImpl attr = new AttributeImpl( "testing" );
+        AttributeSerializerUtils serializer = new AttributeSerializerUtils();
+        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
+    {
+        AttributeImpl attr = new AttributeImpl( "testing" );
+        AttributeSerializerUtils serializer = new AttributeSerializerUtils();
+        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, deserialized.get() );
+        ArrayUtils.isEquals( ba1, deserialized.get( 1 ) );
+    }
+    
+    
+    public void doSerializerSpeedTest() throws IOException
+    {
+        final int limit = 1000000;
+        long start = System.currentTimeMillis();
+        for ( int ii = 0; ii < limit; ii++ )
+        {
+            AttributeImpl attr = new AttributeImpl( "testing" );
+            AttributeSerializerUtils serializer = new AttributeSerializerUtils();
+            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)" );
+    }
+}



Mime
View raw message