Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

How can I optimize the following class?

prepareSharing packs bits on left and prepareMask counts the required bits for encoding integers between zero and max.

public class KeyFactory
{      
  public static short[] prepareSharing( short[] sharing, int mask )
  {
    // Ensure mask is unsigned short
    //
    mask &= 0xFFFF;

    // Search first zero bits
    //
    // BE CAREFUL : raise java.lang.ArrayIndexOutOfBoundsException if there aren't enough bits available
    //
    int i = 0;
    while( ( sharing[i] & 0xFFFF ) == 0xFFFF )
      i++;

    // Handle masks larger than available free bits
    //
    int remaining = ~( sharing[i] & 0xFFFF ) & 0x0000FFFF;

    if( remaining < mask )
    {
      for( ;remaining > 0; remaining >>= 1, mask >>= 1 );      
      sharing[i++] |= 0xFFFF;
    }

    // Pack bits
    //
    int temporary, current = sharing[i];
    for( temporary = ( current | mask ) & 0xFFFF; ( ( current | ( mask << 1 ) ) & 0xFFFF ) > temporary; mask <<= 1, temporary = ( current | mask ) & 0xFFFF );

    sharing[i] = 0;
    sharing[i] |= temporary;

    return sharing;
  }

  public static int prepareMask( int maxCount )
  {
    int mask = 0;

    for( int i = 0; i < 16; i++ )
      if( maxCount >> i > 0 )
        mask |= 1 << i;

    return mask;
  }
}

Tests:

import org.junit.Assert;
import org.junit.Test;

import fr.meuns.render.KeyFactory;

public class TestKeyFactory
{
  @Test
  public void testPrepareMask()
  {
    Assert.assertEquals( 0b0001 ,KeyFactory.prepareMask( 1 ) );
    Assert.assertEquals( 0b0011 ,KeyFactory.prepareMask( 2 ) );
    Assert.assertEquals( 0b0011 ,KeyFactory.prepareMask( 3 ) );
    Assert.assertEquals( 0b0111 ,KeyFactory.prepareMask( 4 ) );
    Assert.assertEquals( 0b0111 ,KeyFactory.prepareMask( 5 ) );
    Assert.assertEquals( 0b0111 ,KeyFactory.prepareMask( 6 ) );
    Assert.assertEquals( 0b0111 ,KeyFactory.prepareMask( 7 ) );

    for( int i = 8; i < 16; i++ )
      Assert.assertEquals( 0b001111 ,KeyFactory.prepareMask( i ) );

    for( int i = 16; i < 32; i++ )
      Assert.assertEquals( 0b011111 ,KeyFactory.prepareMask( i ) );

    for( int i = 32; i < 64; i++ )
      Assert.assertEquals( 0b111111 ,KeyFactory.prepareMask( i ) );
  }

  @Test
  public void testPackSharing_0x0007()
  {
    short[] sharing = new short[] {
      0x0000, 0x0000
    };

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xE000, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFC00, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFF80, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFF0, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFE, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xC000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xF800, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xFF00, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xFFE0, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x0007 );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xFFFC, sharing[1] & 0xFFFF );
  }

  @Test
  public void testPackSharing_0x003F()
  {
    short[] sharing = new short[] {
      0x0000, 0x0000
    };

    sharing = KeyFactory.prepareSharing( sharing, (short)0x003F );    
    Assert.assertEquals( 0xFC00, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x003F );    
    Assert.assertEquals( 0xFFF0, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0x0000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x003F );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xC000, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x003F );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xFF00, sharing[1] & 0xFFFF );

    sharing = KeyFactory.prepareSharing( sharing, (short)0x003F );    
    Assert.assertEquals( 0xFFFF, sharing[0] & 0xFFFF );
    Assert.assertEquals( 0xFFFC, sharing[1] & 0xFFFF );
  }
}
share|improve this question
What's wrong with good old BitSet? – Landei Aug 16 at 14:12
BitSet uses JNI, does a lot of checking and stocks bits in long words. JNI and checking wastes performances. Longs are painful for comparing resulting keys (see posts about signed and unsigned int java mess). Converting long words to short words is bad for performance too. – sylvain Aug 16 at 15:24

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.