/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
import org.apache.hadoop_voltpatches.util.PureJavaCrc32C;
public class HybridCrc32 extends PureJavaCrc32C {
private static final int NATIVE_REDIRECT_SIZE = 150;
@Override
public void update(byte[] b) {
if (b.length > NATIVE_REDIRECT_SIZE) {
CRC32 nativeCRC = new CRC32();
nativeCRC.update(b, 0, b.length);
int crc = (int) nativeCRC.getValue();
update(crc);
}
else {
super.update(b, 0, b.length);
}
}
public void update(ByteBuffer b) {
if (b.remaining() > NATIVE_REDIRECT_SIZE) {
CRC32 nativeCRC = new CRC32();
nativeCRC.update(b);
update((int) nativeCRC.getValue());
return;
}
int len = b.remaining();
int localCrc = crc;
while(len > 7) {
int c0 = b.get() ^ localCrc;
int c1 = b.get() ^ (localCrc >>>= 8);
int c2 = b.get() ^ (localCrc >>>= 8);
int c3 = b.get() ^ (localCrc >>>= 8);
localCrc = (T8_7[c0 & 0xff] ^ T8_6[c1 & 0xff])
^ (T8_5[c2 & 0xff] ^ T8_4[c3 & 0xff]);
localCrc ^= (T8_3[b.get() & 0xff] ^ T8_2[b.get() & 0xff])
^ (T8_1[b.get() & 0xff] ^ T8_0[b.get() & 0xff]);
len -= 8;
}
while(len > 0) {
localCrc = (localCrc >>> 8) ^ T8_0[(localCrc ^ b.get()) & 0xff];
len--;
}
// Publish crc out to object
crc = localCrc;
}
@Override
public void update(byte[] b, int off, int len) {
if (len > NATIVE_REDIRECT_SIZE) {
CRC32 nativeCRC = new CRC32();
nativeCRC.update(b, off, len);
update((int) nativeCRC.getValue());
}
else {
super.update(b, off, len);
}
}
public void updateFromPosition(int off, ByteBuffer b) {
b.limit(b.position());
b.position(off);
update(b);
assert(b.remaining() == 0);
b.limit(b.capacity());
}
}