Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.bookkeeper.proto.checksum;
import io.netty.buffer.ByteBuf;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.zip.CRC32;
import org.apache.bookkeeper.proto.checksum.CRC32DigestManager.CRC32Digest;
/**
* Specialized implementation of CRC32 digest that uses reflection on {@link CRC32} class to get access to
* "updateByteBuffer" method and pass a direct memory pointer.
*/
class DirectMemoryCRC32Digest implements CRC32Digest {
public static boolean isSupported() {
return updateBytes != null;
}
private int crcValue;
@Override
public long getValueAndReset() {
long value = crcValue & 0xffffffffL;
crcValue = 0;
return value;
}
@Override
public void update(ByteBuf buf, int index, int length) {
try {
if (buf.hasMemoryAddress()) {
// Calculate CRC directly from the direct memory pointer
crcValue = (int) updateByteBuffer.invoke(null, crcValue, buf.memoryAddress(), index, length);
} else if (buf.hasArray()) {
// Use the internal method to update from array based
crcValue = updateArray(crcValue, buf.array(), buf.arrayOffset() + index, length);
} else {
// Fallback to data copy if buffer is not contiguous
byte[] b = new byte[length];
buf.getBytes(index, b, 0, length);
crcValue = updateArray(crcValue, b, 0, length);
}
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static int updateArray(int crcValue, byte[] buf, int offset, int length)
throws IllegalAccessException, InvocationTargetException {
return (int) updateBytes.invoke(null, crcValue, buf, offset, length);
}
@Override
public void update(byte[] buffer, int offset, int len) {
try {
crcValue = updateArray(crcValue, buffer, offset, len);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static final Method updateByteBuffer;
private static final Method updateBytes;
static {
// Access CRC32 class private native methods to compute the crc on the ByteBuf direct memory,
// without necessity to convert to a nio ByteBuffer.
Method updateByteBufferMethod = null;
Method updateBytesMethod = null;
try {
updateByteBufferMethod = CRC32.class.getDeclaredMethod("updateByteBuffer", int.class, long.class, int.class,
int.class);
updateByteBufferMethod.setAccessible(true);
updateBytesMethod = CRC32.class.getDeclaredMethod("updateBytes", int.class, byte[].class, int.class,
int.class);
updateBytesMethod.setAccessible(true);
} catch (Throwable e) {
updateByteBufferMethod = null;
updateBytesMethod = null;
}
updateByteBuffer = updateByteBufferMethod;
updateBytes = updateBytesMethod;
}
}