Merge pull request #741 from HeartSaVioR/optimize-crc16-calculation

Optimize CRC16 calculation (with optimization of slot decision)
This commit is contained in:
Jungtaek Lim
2014-09-18 09:54:38 +09:00
2 changed files with 10 additions and 8 deletions

View File

@@ -4,7 +4,7 @@ package redis.clients.util;
* CRC16 Implementation according to CCITT standard * CRC16 Implementation according to CCITT standard
* Polynomial : 1021 (x^16 + x^12 + x^5 + 1) * Polynomial : 1021 (x^16 + x^12 + x^5 + 1)
* *
* @see: http://redis.io/topics/cluster-spec * @see http://redis.io/topics/cluster-spec
* Appendix A. CRC16 reference implementation in ANSI C * Appendix A. CRC16 reference implementation in ANSI C
*/ */
public class JedisClusterCRC16 { public class JedisClusterCRC16 {
@@ -36,22 +36,24 @@ public class JedisClusterCRC16 {
key = key.substring(s+1, e); key = key.substring(s+1, e);
} }
} }
return getCRC16(key) % 16384; // optimization with modulo operator with power of 2
// equivalent to getCRC16(key) % 16384
return getCRC16(key) & (16384 - 1);
} }
/** /**
* Create a CRC16 checksum from the bytes. * Create a CRC16 checksum from the bytes.
* implementation is from mp911de/lettuce * implementation is from mp911de/lettuce, modified with some more optimizations
* *
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @param bytes * @param bytes
* @return CRC16 as integer value * @return CRC16 as integer value
* @see https://github.com/xetorthio/jedis/pull/733#issuecomment-55840331
*/ */
public static int getCRC16(byte[] bytes) { public static int getCRC16(byte[] bytes) {
int crc = 0x0000; int crc = 0x0000;
for (byte b : bytes) { for (byte b : bytes) {
crc = ((crc << 8) ^ LOOKUP_TABLE[((crc >> 8) ^ (b & 0xFF)) & 0xFF]) & 0xFFFF; crc = ((crc << 8) ^ LOOKUP_TABLE[((crc >>> 8) ^ (b & 0xFF)) & 0xFF]);
} }
return crc & 0xFFFF; return crc & 0xFFFF;
} }

View File

@@ -5,13 +5,13 @@ import java.util.Calendar;
import redis.clients.util.JedisClusterCRC16; import redis.clients.util.JedisClusterCRC16;
public class CRC16Benchmark { public class CRC16Benchmark {
private static final int TOTAL_OPERATIONS = 10000000; private static final int TOTAL_OPERATIONS = 100000000;
private static String[] TEST_SET = { private static String[] TEST_SET = {
"", "123456789", "sfger132515", "hae9Napahngaikeethievubaibogiech", "", "123456789", "sfger132515", "hae9Napahngaikeethievubaibogiech",
"AAAAAAAAAAAAAAAAAAAAAA", "Hello, World!" "AAAAAAAAAAAAAAAAAAAAAA", "Hello, World!"
}; };
public static void main(String[] args) { public static void main(String[] args) {
long begin = Calendar.getInstance().getTimeInMillis(); long begin = Calendar.getInstance().getTimeInMillis();
@@ -23,5 +23,5 @@ public class CRC16Benchmark {
System.out.println(((1000 * TOTAL_OPERATIONS) / elapsed) + " ops"); System.out.println(((1000 * TOTAL_OPERATIONS) / elapsed) + " ops");
} }
} }