Hi Stanimir,

I believe this makes the code harder to follow as you now have to read another method to follow the initialization of the arrays: The shifting of crc and secondHalf is also different so it would still be some difference between the two if I'm not mistaken.

Cheers,
Staffan

On 11/06/2014 12:26 PM, Stanimir Simeonoff wrote:
Hi Staffan,
Given the tables in the static class init :
   66     private transient final static int[] byteTable0 = byteTables[0];
   67     private transient final static int[] byteTable1 = byteTables[1];
   68     private transient final static int[] byteTable2 = byteTables[2];
   69     private transient final static int[] byteTable3 = byteTables[3];
   70     private transient final static int[] byteTable4 = byteTables[4];
   71     private transient final static int[] byteTable5 = byteTables[5];
   72     private transient final static int[] byteTable6 = byteTables[6];
   73     private transient final static int[] byteTable7 = byteTables[7];


I was wondering if assigning the tables in the static part  in similar fashion 
would make the code much more readable:
   66     private transient final static int[] byteTable0 = byteTables[idx(0)];
   67     private transient final static int[] byteTable1 = byteTables[idx(1)];
   68     private transient final static int[] byteTable2 = byteTables[idx(2)];
   69     private transient final static int[] byteTable3 = byteTables[idx(3)];
   70     private transient final static int[] byteTable4 = byteTables[idx(4(];
   71     private transient final static int[] byteTable5 = byteTables[idx(5)];
   72     private transient final static int[] byteTable6 = byteTables[idx(6)];
   73     private transient final static int[] byteTable7 = byteTables[idx(7)];
private static int idx(int i){ return ByteOrder.nativeOrder() == 
ByteOrder.LITTLE_ENDIAN?7-i:i;};


Then in the loops you can skip checking the condition, something like:
  296-                 if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
  297-                    crc = byteTable7[crc & 0xFF]
  298-                             ^ byteTable6[(crc >>> 8) & 0xFF]
  299-                             ^ byteTable5[(crc >>> 16) & 0xFF]
  300-                             ^ byteTable4[crc >>> 24]
  301-                             ^ byteTable3[secondHalf & 0xFF]
  302-                             ^ byteTable2[(secondHalf >>> 8) & 0xFF]
  303-                             ^ byteTable1[(secondHalf >>> 16) & 0xFF]
  304-                             ^ byteTable0[secondHalf >>> 24];
  305-                 } else { // ByteOrder.BIG_ENDIAN
  306                     crc = byteTable0[secondHalf & 0xFF]
  307                             ^ byteTable1[(secondHalf >>> 8) & 0xFF]
  308                             ^ byteTable2[(secondHalf >>> 16) & 0xFF]
  309                             ^ byteTable3[secondHalf >>> 24]
  310                             ^ byteTable4[crc & 0xFF]
  311                             ^ byteTable5[(crc >>> 8) & 0xFF]
  312                             ^ byteTable6[(crc >>> 16) & 0xFF]
  313                             ^ byteTable7[crc >>> 24];
  314 -                }
Since the byteTabeleN are properly assigned during the class init based on the 
endianess of the systen. Of course, there won't be any performance benefits 
since hotspot should constant fold the code
but it'll be easier to maintain and read.

Cheers
Stanimir

On Thu, Nov 6, 2014 at 12:18 PM, Staffan Friberg <staffan.frib...@oracle.com <mailto:staffan.frib...@oracle.com>> wrote:

    Anyone have time to be the second reviewer?

    http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07
    <http://cr.openjdk.java.net/%7Esfriberg/JDK-6321472/webrev.07>

    The CCC request has been approved for the new API.

    Regards;
    Staffan


    On 10/22/2014 12:16 AM, Staffan Friberg wrote:

        Thanks for the review. Updated the @implSpec.

        Also includes Peter's good catch.

        Webrev:
        http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.06
        <http://cr.openjdk.java.net/%7Esfriberg/JDK-6321472/webrev.06>

        //Staffan

        On 10/21/2014 02:09 PM, Xueming Shen wrote:

            Staffan,

            Thanks for the package.html update.

            Just wonder if it would be better to use

                buffer.remaining(), instead of the buffer.limit() -
            buffer.position()

            in Checksum.udpate(ByteBuffer)'s #implSpec

            The rest looks fine for me.

            -Sherman

            On 10/21/2014 01:11 PM, Staffan Friberg wrote:

                Converted.

                http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.05
                <http://cr.openjdk.java.net/%7Esfriberg/JDK-6321472/webrev.05>

                //Staffan

                On 10/21/2014 12:34 PM, Joe Darcy wrote:

                    Hi Staffan,

                    If you are updating package.html, please also hg
                    mv the file to be a package-info.java file with
                    the equivalent javadoc.

                    Thanks,

                    -Joe

                    On 10/21/2014 11:49 AM, Staffan Friberg wrote:

                        Hi,

                        Got an offline comment that the package.html
                        should be update as well to cover CRC-32C.

                        Otherwise there are no code changes in this
                        new webrev.

                        
http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04
                        
<http://cr.openjdk.java.net/%7Esfriberg/JDK-6321472/webrev.04>

                        //Staffan

                        On 10/21/2014 10:28 AM, Staffan Friberg wrote:

                            Hi Peter,

                            Thanks for the comments..


                                  217                 if
                                (Unsafe.ADDRESS_SIZE == 4) {
                                  218                     // On 32 bit
                                platforms read two ints instead of a
                                single 64bit long

                                When you're reading from byte[] using
                                Unsafe (updateBytes), you have the
                                option of reading 64bit values on
                                64bit platforms. When you're reading
                                from DirectByteBuffer memory
                                (updateDirectByteBuffer), you're only
                                using 32bit reads.

                            I will add a comment in the code for this
                            decision. The reason is that read a long
                            results in slightly worse performance in
                            this case, in updateBytes it is faster. I
                            was able to get it to run slightly faster
                            by working directly with the address
                            instead of always adding address + off,
                            but this makes things worse in the 32bit
                            case since all calculation will now be
                            using long variables. So using the getInt
                            as in the current code feels like the best
                            solution as it strikes the best balance
                            between 32 and 64bit. Below is how
                            updateByteBuffer looked with the rewrite I
                            mentioned.


                             ong address = ((DirectBuffer)
                            buffer).address();
                             crc = updateDirectByteBuffer(crc, address
                            + pos, address + limit);


                                 private static int
                            updateDirectByteBuffer(int crc, long adr,
                            long end) {

                                    // Do only byte reads for arrays
                            so short they can't be aligned
                                    if (end - adr >= 8) {

                                        // align on 8 bytes
                                        int alignLength = (8 - (int)
                            (adr & 0x7)) & 0x7;
                                        for (long alignEnd = adr +
                            alignLength; adr < alignEnd; adr++) {
                                            crc = (crc >>> 8)
                                                    ^ byteTable[(crc ^
                            UNSAFE.getByte(adr)) & 0xFF];
                                        }

                                        if (ByteOrder.nativeOrder() ==
                            ByteOrder.BIG_ENDIAN) {
                                            crc =
                            Integer.reverseBytes(crc);
                                        }

                                        // slicing-by-8
                                        for (; adr < (end -
                            Long.BYTES); adr += Long.BYTES) {
                                            int firstHalf;
                                            int secondHalf;
                                            if (Unsafe.ADDRESS_SIZE ==
                            4) {
                                                // On 32 bit platforms
                            read two ints instead of a single 64bit long
                                                firstHalf =
                            UNSAFE.getInt(adr);
                                                secondHalf =
                            UNSAFE.getInt(adr + Integer.BYTES);
                                            } else {
                                                long value =
                            UNSAFE.getLong(adr);
                                                if
                            (ByteOrder.nativeOrder() ==
                            ByteOrder.LITTLE_ENDIAN) {
                                                    firstHalf = (int)
                            value;
                                                    secondHalf = (int)
                            (value >>> 32);
                                                } else { //
                            ByteOrder.BIG_ENDIAN
                                                    firstHalf = (int)
                            (value >>> 32);
                                                    secondHalf = (int)
                            value;
                                                }
                                            }
                                            crc ^= firstHalf;
                                            if
                            (ByteOrder.nativeOrder() ==
                            ByteOrder.LITTLE_ENDIAN) {
                                                crc = byteTable7[crc &
                            0xFF]
                                                        ^
                            byteTable6[(crc >>> 8) & 0xFF]
                                                        ^
                            byteTable5[(crc >>> 16) & 0xFF]
                                                        ^
                            byteTable4[crc >>> 24]
                                                        ^
                            byteTable3[secondHalf & 0xFF]
                                                        ^
                            byteTable2[(secondHalf >>> 8) & 0xFF]
                                                        ^
                            byteTable1[(secondHalf >>> 16) & 0xFF]
                                                        ^
                            byteTable0[secondHalf >>> 24];
                                            } else { //
                            ByteOrder.BIG_ENDIAN
                                                crc =
                            byteTable0[secondHalf & 0xFF]
                                                        ^
                            byteTable1[(secondHalf >>> 8) & 0xFF]
                                                        ^
                            byteTable2[(secondHalf >>> 16) & 0xFF]
                                                        ^
                            byteTable3[secondHalf >>> 24]
                                                        ^
                            byteTable4[crc & 0xFF]
                                                        ^
                            byteTable5[(crc >>> 8) & 0xFF]
                                                        ^
                            byteTable6[(crc >>> 16) & 0xFF]
                                                        ^
                            byteTable7[crc >>> 24];
                                            }
                                        }

                                        if (ByteOrder.nativeOrder() ==
                            ByteOrder.BIG_ENDIAN) {
                                            crc =
                            Integer.reverseBytes(crc);
                                        }
                                    }

                                    // Tail
                                    for (; adr < end; adr++) {
                                        crc = (crc >>> 8)
                                                ^ byteTable[(crc ^
                            UNSAFE.getByte(adr)) & 0xFF];
                                    }

                                    return crc;
                                }



                                Also, in updateBytes, the usage of
                                
Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE
                                to index a byte array sounds a little
                                scary. To be ultra portable you could
                                check that ARRAY_BYTE_INDEX_SCALE == 1
                                first and refuse to use Unsafe for
                                byte arrays if it is not 1. Then use
                                Integer.BYTES/Long.BYTES to manipulate
                                'offsets' instead. In
                                updateDirectByteBuffer it would be
                                more appropriate to use
                                Integer.BYTES/Long.BYTES too.

                            Good idea. Added a check in the initial if
                            statement and it will get automatically
                            optimized away.

                                  225 firstHalf = (int) (value &
                                0xFFFFFFFF);
226 secondHalf = (int) (value >>> 32);
                                  227                     } else { //
                                ByteOrder.BIG_ENDIAN
228 firstHalf = (int) (value >>> 32); 229 secondHalf = (int) (value & 0xFFFFFFFF);

                                firstHalf = (int) value; // this is
                                equivalent for line 225
                                secondHalf = (int) value; // this is
                                equivalent for line 229

                            Done.

                            Here is the latest webrev,
                            
http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03
                            
<http://cr.openjdk.java.net/%7Esfriberg/JDK-6321472/webrev.03>

                            Cheers,
                            Staffan









Reply via email to