You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Linda Lee <li...@sleepycat.com> on 2004/04/16 23:17:11 UTC

Re: [bdbje] [rms] Using int verses Integer and native key/value ordering


Alex Karasulu wrote:

>Hi,
>
>It's me again got a couple more questions:
>
>1). I peeked at the way an Integer is serialized in the TupleBinding 
>class.  It appears as though the native sorting order of integer keys 
>and values will be the natural integer order.  Just double checking
>so I don't need to write a comparator for an Integer key or value right?
>  
>
That's right -- no comparators are needed. From 
http://www.sleepycat.com/docs/ref/bdb_tuple/intro.html:

    /Tuples are useful as keys because they have a meaningful sort
    order, while serialized objects do not. This is because the binary
    data for a tuple is written in such a way that its raw byte ordering
    provides a useful sort order. For example, strings in tuples are
    written with a null terminator rather than with a leading length./

>2). Also is there a way to not have to wrap primitive types using the
>binding API's - basically is there some means to just setData on an entry
>but get the binding to produce a byte[] from a int and not an Integer
>  
>
Mark is the expert here, but you can use the tuple classes to create 
your own custom binding. Or you could use 
com.sleepycat.bind.tuple.TupleInput, TupleOutput  to read and write 
primitive types to a byte buffer. See 
http://www.sleepycat.com/jedocs/java/index.html.

The general notion is that you create a TupleBinding, using the 
TupleInput/Output to get you from your object to the byte array, but you 
could also use them independently.  The Getting Started Guide has some 
examples: 
http://www.sleepycat.com/jedocs/GettingStartedGuide/bindAPI.html#customTuple


Regards,

Linda
Sleepycat Software

Re: [bdbje] [rms] Using int verses Integer and native key/value ordering

Posted by Mark Hayes <ma...@sleepycat.com>.
On Apr 19, 2004, at 11:18 AM, Alex Karasulu wrote:

> Now after my tests showed a nominal 7% improvement using primitives
> over wrappers I realized this was stupid of me to do.  However you'll
> hear this argument over and over again and not every one is going to
> test this out.  They'll complain about though :-).  Might save you an
> email or two just to expose it - that's my take now that I have the
> numbas after the stress tests.  Plus it just completes the picture.

I think your opinion is very reasonable.  I have filed an enhancement 
request (SR#10138) internally and we'll consider adding this.

> BTW your Binding API's are very nice - I like them.  It would be
> nice to have such an API in general.  I see many incarnations out
> there like the Jakarta-commons convert project in the sandbox, but
> none are as simple and intuitive as this one.

Thank you very much!  I hope it makes your job easier in using JE.

It is possible to use the bind package independently of JE proper, 
although you must import the DatabaseEntry class from the je package.

Mark


RE: [bdbje] [rms] Using int verses Integer and native key/value ordering

Posted by Alex Karasulu <ao...@bellsouth.net>.
Hey Mark,

Thanks for the response.

> -----Original Message-----
> From: Mark Hayes [mailto:mark@sleepycat.com]

> Your questions on this have me thinking about a possible addition to
> our binding API.  Currently, TupleBinding has a static method,
> getPrimitiveBinding, that returns a binding for a given primitive
> wrapper class.  As an alternative, we could expose the (currently
> private) IntegerBinding, FloatBinding, etc, classes, and add methods to
> those classes that take "int", "float", etc, types.
> 
> Do you think that would be a worthwhile addition?  I'm not promising
> that we would do this, as I'm sure you understand, but I'm very
> interested in your opinion.

Funny you mention that because I took these methods (just for the 
primitive int for now) and stuffed a copy of them into a utility 
class JePrimitiveCodecs.java which is attached.  You probably know 
what's in there better than anyone :-).  Basically this is how I 
tested the primitive verses wrapper approach.  Here's what the code 
looks like the variable 'b' btw is the binding gotten via 
TupleBinding.getPrimitiveBinding(Integer.class):

-- USING PRIMITIVES --

    public void testIntStress() throws Exception
    {
        for ( int ii = 10000; ii >= 0; ii-- )
        {
            if ( ii % 1000 == 0 )
            {
                System.out.print( "." ) ;
            }

            JePrimitiveCodecs.encodeInt( ii, key ) ;
            JePrimitiveCodecs.encodeInt( ii, value ) ;
            db.put( null, key, value ) ;

            JePrimitiveCodecs.encodeInt( ii + 1, value ) ;
            db.put( null, key, value ) ;

            JePrimitiveCodecs.encodeInt( ii + 2, value ) ;
            db.put( null, key, value ) ;

            JePrimitiveCodecs.encodeInt( ii + 3, value ) ;
            db.put( null, key, value ) ;

            JePrimitiveCodecs.encodeInt( ii + 4, value ) ;
            db.put( null, key, value ) ;

            JePrimitiveCodecs.encodeInt( ii + 5, value ) ;
            db.put( null, key, value ) ;
        }
    }

-- USING OBJECT WRAPPERS --

    public void testIntegerStress() throws Exception
    {
        for ( int ii = 10000; ii >= 0; ii-- )
        {
            if ( ii % 1000 == 0 )
            {
                System.out.print( "." ) ;
            }

            Integer wrapper = new Integer( ii ) ;
            b.objectToEntry( wrapper, key ) ;

            b.objectToEntry( wrapper, value ) ;
            db.put( null, key, value ) ;

            b.objectToEntry( new Integer( ii + 1 ), value ) ;
            db.put( null, key, value ) ;

            b.objectToEntry( new Integer( ii + 2 ), value ) ;
            db.put( null, key, value ) ;

            b.objectToEntry( new Integer( ii + 3 ), value ) ;
            db.put( null, key, value ) ;

            b.objectToEntry( new Integer( ii + 4 ), value ) ;
            db.put( null, key, value ) ;

            b.objectToEntry( new Integer( ii + 5 ), value ) ;
            db.put( null, key, value ) ;
        }
    }

Now after my tests showed a nominal 7% improvement using primitives 
over wrappers I realized this was stupid of me to do.  However you'll 
hear this argument over and over again and not every one is going to 
test this out.  They'll complain about though :-).  Might save you an 
email or two just to expose it - that's my take now that I have the 
numbas after the stress tests.  Plus it just completes the picture.

BTW your Binding API's are very nice - I like them.  It would be 
nice to have such an API in general.  I see many incarnations out 
there like the Jakarta-commons convert project in the sandbox, but 
none are as simple and intuitive as this one.  

Alex



Re: [bdbje] [rms] Using int verses Integer and native key/value ordering

Posted by Mark Hayes <ma...@sleepycat.com>.
On Apr 16, 2004, at 2:17 PM, Linda Lee wrote:

>> 2). Also is there a way to not have to wrap primitive types using the
>> binding API's - basically is there some means to just setData on an  
>> entry
>> but get the binding to produce a byte[] from a int and not an Integer
>
>  Mark is the expert here, but you can use the tuple classes to create  
> your own custom binding. Or you could use  
> com.sleepycat.bind.tuple.TupleInput, TupleOutput  to read and write  
> primitive types to a byte buffer. See  
> http://www.sleepycat.com/jedocs/java/index.html.
>
>  The general notion is that you create a TupleBinding, using the  
> TupleInput/Output to get you from your object to the byte array, but  
> you could also use them independently.  The Getting Started Guide has  
> some examples:  
> http://www.sleepycat.com/jedocs/GettingStartedGuide/ 
> bindAPI.html#customTuple

There is currently no way to use bindings to operate on primitive types  
directly.  To do that, we would need to add methods for getting and  
setting each type of primitive.  Plus, in order to use bindings with  
collections, the bindings have to support the wrapper classes, since  
collection methods all take and return Objects.

As you say in your other post, the wrapper classes don't add  
significant performance overhead.  Using wrapper classes is a slight  
inconvenience, but the eventual solution to that problem is to use the  
auto-boxing feature of Java 1.5.

However, as Linda mentioned, if you want to optimize for a particular  
case you can create a custom tuple binding that had methods for get/set  
of the "int" type, for example.  I'm happy to help with that if you're  
interested.

Your questions on this have me thinking about a possible addition to  
our binding API.  Currently, TupleBinding has a static method,  
getPrimitiveBinding, that returns a binding for a given primitive  
wrapper class.  As an alternative, we could expose the (currently  
private) IntegerBinding, FloatBinding, etc, classes, and add methods to  
those classes that take "int", "float", etc, types.

Do you think that would be a worthwhile addition?  I'm not promising  
that we would do this, as I'm sure you understand, but I'm very  
interested in your opinion.

Mark