remove bytes subproject, add TreeMultiMap

main
Jörg Prante 2 years ago
parent a101c4f4aa
commit 7c925a6357

@ -1,5 +0,0 @@
This work is derived from
https://github.com/OpenHFT/Chronicle-Bytes
Licensed under the Apache License, Version 2.0

@ -1,6 +0,0 @@
dependencies {
api libs.chronicle.core
testImplementation libs.junit.vintage.engine
testImplementation libs.junit4
testImplementation libs.affinity
}

@ -1,72 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.algo.BytesStoreHash;
import net.openhft.chronicle.core.io.AbstractReferenceCounted;
import java.nio.BufferUnderflowException;
public abstract class AbstractBytesStore<B extends BytesStore<B, Underlying>, Underlying>
extends AbstractReferenceCounted
implements BytesStore<B, Underlying> {
protected AbstractBytesStore() {
}
protected AbstractBytesStore(boolean monitored) {
super(monitored);
}
@Override
public int peekUnsignedByte(long offset) throws BufferUnderflowException {
return offset >= readLimit() ? -1 : readUnsignedByte(offset);
}
@Override
public int hashCode() {
return BytesStoreHash.hash32(this);
}
@Override
public long readPosition() {
return 0L;
}
@Override
public long readRemaining() {
return readLimit() - readPosition();
}
@Override
public long writeRemaining() {
return writeLimit() - writePosition();
}
@Override
public long start() {
return 0L;
}
@Override
protected boolean performReleaseInBackground() {
return isDirectMemory();
}
}

@ -1,332 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.annotation.Java9;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.UTFDataFormatException;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@SuppressWarnings("rawtypes")
public enum AppendableUtil {
;
public static void setCharAt( Appendable sb, int index, char ch)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).setCharAt(index, ch);
else if (sb instanceof Bytes)
((Bytes) sb).writeByte(index, ch);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void parseUtf8( BytesStore bs, StringBuilder sb, boolean utf, int length) throws UTFDataFormatRuntimeException {
BytesInternal.parseUtf8(bs, bs.readPosition(), sb, utf, length);
}
@ForceInline
public static void setLength( Appendable sb, int newLength)
throws BufferUnderflowException, IllegalArgumentException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).setLength(newLength);
else if (sb instanceof Bytes)
((Bytes) sb).readPositionRemaining(0, newLength);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void append( Appendable sb, double value)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).append(value);
else if (sb instanceof Bytes)
((Bytes) sb).append(value);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void append( Appendable sb, long value)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).append(value);
else if (sb instanceof Bytes)
((Bytes) sb).append(value);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static <ACS extends Appendable & CharSequence> void append( ACS sb, String str) {
try {
sb.append(str);
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static void read8bitAndAppend( StreamingDataInput bytes,
StringBuilder appendable,
StopCharsTester tester) {
while (true) {
int c = bytes.readUnsignedByte();
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
if (bytes.readRemaining() == 0)
return;
}
}
public static void readUTFAndAppend( StreamingDataInput bytes,
Appendable appendable,
StopCharsTester tester)
throws BufferUnderflowException {
try {
readUtf8AndAppend(bytes, appendable, tester);
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static void readUtf8AndAppend( StreamingDataInput bytes,
Appendable appendable,
StopCharsTester tester)
throws BufferUnderflowException, IOException {
while (true) {
int c = bytes.readUnsignedByte();
if (c >= 128) {
bytes.readSkip(-1);
break;
}
// this is used for array class such as !type byte[]
if (c == '[' && bytes.peekUnsignedByte() == ']') {
appendable.append((char) c);
appendable.append((char) bytes.readUnsignedByte());
if (bytes.readRemaining() == 0)
return;
continue;
}
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
if (bytes.readRemaining() == 0)
return;
}
for (int c; (c = bytes.readUnsignedByte()) >= 0; ) {
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
/* 0xxxxxxx */
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
break;
case 12:
case 13: {
/* 110x xxxx 10xx xxxx */
int char2 = bytes.readUnsignedByte();
if ((char2 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char2));
int c2 = (char) (((c & 0x1F) << 6) |
(char2 & 0x3F));
if (tester.isStopChar(c2, bytes.peekUnsignedByte()))
return;
appendable.append((char) c2);
break;
}
case 14: {
/* 1110 xxxx 10xx xxxx 10xx xxxx */
int char2 = bytes.readUnsignedByte();
int char3 = bytes.readUnsignedByte();
if (((char2 & 0xC0) != 0x80))
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char2));
if ((char3 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char3));
int c3 = (char) (((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
(char3 & 0x3F));
if (tester.isStopChar(c3, bytes.peekUnsignedByte()))
return;
appendable.append((char) c3);
break;
}
default:
/* 10xx xxxx, 1111 xxxx */
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(c));
}
}
}
public static void parse8bit_SB1( Bytes bytes, StringBuilder sb, int length)
throws BufferUnderflowException {
if (length > bytes.readRemaining())
throw new BufferUnderflowException();
NativeBytesStore nbs = (NativeBytesStore) bytes.bytesStore();
long offset = bytes.readPosition();
int count = BytesInternal.parse8bit_SB1(offset, nbs, sb, length);
bytes.readSkip(count);
}
public static void parse8bit( StreamingDataInput bytes, Appendable appendable, int utflen)
throws BufferUnderflowException, IOException {
if (appendable instanceof StringBuilder) {
final StringBuilder sb = (StringBuilder) appendable;
if (bytes instanceof Bytes && ((Bytes) bytes).bytesStore() instanceof NativeBytesStore) {
parse8bit_SB1((Bytes) bytes, sb, utflen);
} else {
BytesInternal.parse8bit1(bytes, sb, utflen);
}
} else {
BytesInternal.parse8bit1(bytes, appendable, utflen);
}
}
public static <ACS extends Appendable & CharSequence> void append(ACS a, CharSequence cs, long start, long len) {
if (a instanceof StringBuilder) {
if (cs instanceof Bytes)
((StringBuilder) a).append(Bytes.toString(((Bytes) cs), start, len));
else
((StringBuilder) a).append(cs.subSequence(Maths.toInt32(start), Maths.toInt32(len)));
} else if (a instanceof Bytes) {
((Bytes) a).appendUtf8(cs, Maths.toInt32(start), Maths.toInt32(len));
} else {
throw new UnsupportedOperationException();
}
}
public static long findUtf8Length( CharSequence str) throws IndexOutOfBoundsException {
int strlen = str.length();
long utflen = strlen;/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i++) {
char c = str.charAt(i);
if (c <= 0x007F) {
continue;
}
if (c <= 0x07FF) {
utflen++;
} else {
utflen += 2;
}
}
return utflen;
}
@Java9
public static long findUtf8Length( byte[] bytes, byte coder) {
long utflen;
if (coder == 0) {
int strlen = bytes.length;
utflen = bytes.length;
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < strlen; i++) {
int b = (bytes[i] & 0xFF);
if (b > 0x007F) {
utflen++;
}
}
} else {
int strlen = bytes.length;
utflen = 0;/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i += 2) {
char c = (char) (((bytes[i + 1] & 0xFF) << 8) | (bytes[i] & 0xFF));
if (c <= 0x007F) {
utflen += 1;
continue;
}
if (c <= 0x07FF) {
utflen += 2;
} else {
utflen += 3;
}
}
}
return utflen;
}
@Java9
public static long findUtf8Length( byte[] chars) {
long utflen = 0; /* use charAt instead of copying String to char array */
int strlen = chars.length;
for (int i = 0; i < strlen; i++) {
int c = chars[i] & 0xFF; // unsigned byte
if (c == 0) { // we have hit end of string
break;
}
if (c >= 0xF0) {
utflen += 4;
i += 3;
} else if (c >= 0xE0) {
utflen += 3;
i += 2;
} else if (c >= 0xC0) {
utflen += 2;
i += 1;
} else {
utflen += 1;
}
}
return utflen;
}
public static long findUtf8Length( char[] chars) {
long utflen = chars.length;/* use charAt instead of copying String to char array */
for (char c : chars) {
if (c <= 0x007F) {
continue;
}
if (c <= 0x07FF) {
utflen++;
} else {
utflen += 2;
}
}
return utflen;
}
}

@ -1,55 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.util.AbstractInvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
public class BinaryBytesMethodWriterInvocationHandler extends AbstractInvocationHandler implements BytesMethodWriterInvocationHandler {
private final Function<Method, MethodEncoder> methodToId;
@SuppressWarnings("rawtypes")
private final BytesOut out;
private final Map<Method, MethodEncoder> methodToIdMap = new LinkedHashMap<>();
@SuppressWarnings("rawtypes")
public BinaryBytesMethodWriterInvocationHandler(Function<Method, MethodEncoder> methodToId, BytesOut out) {
super(HashMap::new);
this.methodToId = methodToId;
this.out = out;
}
@Override
protected Object doInvoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
MethodEncoder info = methodToIdMap.computeIfAbsent(method, methodToId);
if (info == null) {
Jvm.warn().on(getClass(), "Unknown method " + method + " ignored");
return null;
}
out.comment(method.getName());
out.writeStopBit(info.messageId());
info.encode(args, out);
return null;
}
}

@ -1,126 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public interface BinaryWireCode {
// sequence of length 0 - 255 bytes
int BYTES_LENGTH8 = 0x80;
// sequence of length 0 - 2^16-1 bytes
int BYTES_LENGTH16 = 0x81;
// sequence of length 0 - 2^32-1
int BYTES_LENGTH32 = 0x82;
// sequence of length 0 - 255
// public static final int BYTES_LENGTH64 = 0x83;
int FIELD_ANCHOR = 0x87;
int ANCHOR = 0x88;
int UPDATED_ALIAS = 0x89;
// an array of unsigned bytes
int U8_ARRAY = 0x8A;
// public static final int U16_ARRAY = 0x8B;
// public static final int I32_ARRAY = 0x8C;
int I64_ARRAY = 0x8D;
int PADDING32 = 0x8E;
int PADDING = 0x8F;
int FLOAT32 = 0x90;
int FLOAT64 = 0x91;
int FLOAT_STOP_2 = 0x92;
int FLOAT_STOP_4 = 0x94;
int FLOAT_STOP_6 = 0x96;
int FLOAT_SET_LOW_0 = 0x9A;
int FLOAT_SET_LOW_2 = 0x9B;
int FLOAT_SET_LOW_4 = 0x9C;
// 0x98 - 0x9F
int UUID = 0xA0;
int UINT8 = 0xA1;
int UINT16 = 0xA2;
int UINT32 = 0xA3;
int INT8 = 0xA4;
int INT16 = 0xA5;
int INT32 = 0xA6;
int INT64 = 0xA7;
int SET_LOW_INT8 = 0xA8;
int SET_LOW_INT16 = 0xA9;
// public static final int FIXED_5 = 0xAA;
// public static final int FIXED_4 = 0xAB;
// public static final int FIXED_3 = 0xAC;
// public static final int FIXED_2 = 0xAD;
int STOP_BIT = 0xAE;
int INT64_0x = 0xAF;
int FALSE = 0xB0;
int TRUE = 0xB1;
int TIME = 0xB2;
int DATE = 0xB3;
int DATE_TIME = 0xB4;
int ZONED_DATE_TIME = 0xB5;
int TYPE_PREFIX = 0xB6;
int FIELD_NAME_ANY = 0xB7;
int STRING_ANY = 0xB8;
int EVENT_NAME = 0xB9;
int FIELD_NUMBER = 0xBA;
int NULL = 0xBB;
int TYPE_LITERAL = 0xBC;
int EVENT_OBJECT = 0xBD;
int COMMENT = 0xBE;
int HINT = 0xBF;
int FIELD_NAME0 = 0xC0;
// ...
int FIELD_NAME31 = 0xDF;
int STRING_0 = 0xE0;
// ...
int STRING_31 = 0xFF;
String[] STRING_FOR_CODE = _stringForCode(BinaryWireCode.class);
static String[] _stringForCode(Class clazz) {
String[] stringForCode = new String[256];
try {
for ( Field field : clazz.getDeclaredFields()) {
if (field.getType() == int.class)
stringForCode[field.getInt(null)] = field.getName();
else if (field.getType() == byte.class)
stringForCode[field.getByte(null) & 0xFF] = field.getName();
}
for (int i = FIELD_NAME0; i <= FIELD_NAME31; i++)
stringForCode[i] = "FIELD_" + i;
for (int i = STRING_0; i <= STRING_31; i++)
stringForCode[i] = "STRING_" + i;
for (int i = 0; i < stringForCode.length; i++) {
if (stringForCode[i] == null)
if (i <= ' ' || i >= 127)
stringForCode[i] = "Unknown_0x" + Integer.toHexString(i).toUpperCase();
else
stringForCode[i] = "Unknown_" + (char) i;
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
return stringForCode;
}
}

@ -1,308 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.UnsafeText;
import org.jetbrains.annotations.NotNull;
import java.io.Writer;
import java.math.BigDecimal;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
/**
* Methods to append text to a Bytes. This extends the Appendable interface.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface ByteStringAppender<B extends ByteStringAppender<B>> extends StreamingDataOutput<B>, Appendable {
/**
* @return these Bytes as a Writer
*/
default Writer writer() {
return new ByteStringWriter(this);
}
/**
* Append a char in UTF-8
*
* @param ch to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append(char ch) throws BufferOverflowException {
BytesInternal.appendUtf8Char(this, ch);
return (B) this;
}
/**
* Append a characters in UTF-8
*
* @param cs to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append( CharSequence cs) throws BufferOverflowException {
if (cs.length() == 0)
return (B) this;
try {
return append(cs, 0, cs.length());
} catch (IndexOutOfBoundsException e) {
throw new AssertionError(e);
}
}
/**
* Append a boolean as T or F
*
* @param flag to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(boolean flag) throws BufferOverflowException {
return append(flag ? 'T' : 'F');
}
/**
* Append an int in decimal
*
* @param value to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(int value) throws BufferOverflowException {
BytesInternal.appendBase10(this, value);
return (B) this;
}
/**
* Append a long in decimal
*
* @param value to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(long value) throws BufferOverflowException {
if (value == (int) value)
BytesInternal.appendBase10(this, (int) value);
else
BytesInternal.appendBase10(this, value);
return (B) this;
}
default B appendBase(long value, int base) throws BufferOverflowException {
BytesInternal.append(this, value, base);
return (B) this;
}
default B appendBase16(long value) throws BufferOverflowException {
BytesInternal.appendBase16(this, value, 1);
return (B) this;
}
default B appendBase16(long value, int minDigits) throws BufferOverflowException {
BytesInternal.appendBase16(this, value, minDigits);
return (B) this;
}
/**
* Append a long in decimal with a given number of decimal places. Print value * 10^-decimalPlaces
*
* @param value to append
* @param decimalPlaces to shift the decimal place.
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B appendDecimal(long value, int decimalPlaces) throws BufferOverflowException {
BytesInternal.appendDecimal(this, value, decimalPlaces);
return (B) this;
}
/**
* Append a float in decimal notation
*
* @param f to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(float f) throws BufferOverflowException {
float f2 = Math.abs(f);
if (f2 > 1e6 || f2 < 1e-3) {
return append(Float.toString(f));
}
int precision = (int) Math.floor(6 - Math.log10(f2));
long tens = Maths.tens(precision);
return append((double) Math.round(f * tens) / tens);
}
/**
* Append a double in decimal notation
*
* @param d to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(double d) throws BufferOverflowException {
BytesInternal.append(this, d);
return (B) this;
}
/**
* Append a double in decimal notation to a specific number of decimal places. Trailing zeros are not truncated.
* <p>
* If the number would normally be printed with more decimal places, the number is rounded.
*
* @param d to append
* @param decimalPlaces to always produce
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(double d, int decimalPlaces) throws BufferOverflowException {
if (decimalPlaces < 0)
throw new IllegalArgumentException();
if (decimalPlaces < 18) {
double d2 = d * Maths.tens(decimalPlaces);
if (d2 < Long.MAX_VALUE && d2 > Long.MIN_VALUE) {
// changed from java.lang.Math.round(d2) as this was shown up to cause latency
long round = d2 > 0.0 ? (long) (d2 + 0.5) : (long) (d2 - 0.5);
if (canWriteDirect(20 + decimalPlaces)) {
long address = addressForWritePosition();
long address2 = UnsafeText.appendBase10d(address, round, decimalPlaces);
writeSkip(address2 - address);
} else {
appendDecimal(round, decimalPlaces);
}
return (B) this;
}
}
return append(d);
}
/**
* Append a portion of a String to the Bytes in UTF-8.
*
* @param cs to copy
* @param start index of the first char inclusive
* @param end index of the last char exclusive.
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append( CharSequence cs, int start, int end)
throws IndexOutOfBoundsException, BufferOverflowException {
BytesInternal.appendUtf8(this, cs, start, end - start);
return (B) this;
}
/**
* Append a String to the Bytes in ISO-8859-1
*
* @param cs to write
* @return this
* @throws BufferOverflowException If the string as too large to write in the capacity available
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
default B append8bit( CharSequence cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return append8bit(cs, 0, cs.length());
}
default B append8bit( BytesStore bs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return write(bs, 0L, bs.readRemaining());
}
default B append8bit( String cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return append8bit(cs, 0, cs.length());
}
/**
* Append a portion of a String to the Bytes in ISO-8859-1
*
* @param cs to copy
* @param start index of the first char inclusive
* @param end index of the last char exclusive.
* @return this
* @throws BufferOverflowException If the string as too large to write in the capacity available
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IndexOutOfBoundsException if the start or the end are not valid for the CharSequence
*/
default B append8bit( CharSequence cs, int start, int end)
throws IllegalArgumentException, BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
if (cs instanceof BytesStore) {
return write((BytesStore) cs, (long) start, end);
}
for (int i = start; i < end; i++) {
char c = cs.charAt(i);
if (c > 255) c = '?';
writeByte((byte) c);
}
return (B) this;
}
default B append8bit( BytesStore bs, long start, long end)
throws IllegalArgumentException, BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return write(bs, start, end);
}
default B appendDateMillis(long dateInMillis) {
BytesInternal.appendDateMillis(this, dateInMillis);
return (B) this;
}
default B appendTimeMillis(long timeOfDayInMillis) {
BytesInternal.appendTimeMillis(this, timeOfDayInMillis % 86400_000L);
return (B) this;
}
default B append( BigDecimal bigDecimal) {
append(bigDecimal.toString());
return (B) this;
}
}

@ -1,252 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Reader;
import java.math.BigDecimal;
import java.nio.BufferUnderflowException;
/**
* Supports parsing bytes as text. You can parse them as special or white space terminated text.
*/
interface ByteStringParser<B extends ByteStringParser<B>> extends StreamingDataInput<B> {
/**
* Access these bytes as an ISO-8859-1 encoded Reader
*
* @return as a Reader
*/
default Reader reader() {
return new ByteStringReader(this);
}
/**
* Return true or false, or null if it could not be detected
* as true or false. Case is not important
* <p>
* <p>false: f, false, n, no, 0
* <p>
* <p>true: t, true, y, yes, 1
*
* @param tester to detect the end of the text.
* @return true, false, or null if neither.
*/
default Boolean parseBoolean( StopCharTester tester) {
return BytesInternal.parseBoolean(this, tester);
}
default Boolean parseBoolean() {
return BytesInternal.parseBoolean(this, StopCharTesters.NON_ALPHA_DIGIT);
}
/**
* parse text with UTF-8 decoding as character terminated.
*
* @param stopCharTester to check if the end has been reached.
* @return the text as a String.
*/
@ForceInline
default String parseUtf8( StopCharTester stopCharTester) {
return BytesInternal.parseUtf8(this, stopCharTester);
}
@Deprecated(/* to be removed in x.22 */)
default String parseUTF( StopCharTester stopCharTester) {
return parseUtf8(stopCharTester);
}
/**
* parse text with UTF-8 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharTester to check if the end has been reached.
*/
@ForceInline
default void parseUtf8( Appendable buffer, StopCharTester stopCharTester) throws BufferUnderflowException {
BytesInternal.parseUtf8(this, buffer, stopCharTester);
}
@Deprecated(/* to be removed in x.22 */)
default void parseUTF( Appendable buffer, StopCharTester stopCharTester) throws BufferUnderflowException {
parseUtf8(buffer, stopCharTester);
}
/**
* parse text with UTF-8 decoding as one or two character terminated.
*
* @param buffer to populate
* @param stopCharsTester to check if the end has been reached.
*/
@ForceInline
default void parseUtf8( Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException, IORuntimeException {
BytesInternal.parseUtf8(this, buffer, stopCharsTester);
}
@Deprecated(/* to be removed in x.22 */)
default void parseUTF( Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException, IORuntimeException {
parseUtf8(buffer, stopCharsTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharTester to check if the end has been reached.
*/
@SuppressWarnings("rawtypes")
@ForceInline
default void parse8bit(Appendable buffer, StopCharTester stopCharTester)
throws BufferUnderflowException {
if (buffer instanceof StringBuilder)
BytesInternal.parse8bit(this, (StringBuilder) buffer, stopCharTester);
else
BytesInternal.parse8bit(this, (Bytes) buffer, stopCharTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param stopCharTester to check if the end has been reached.
*/
default String parse8bit( StopCharTester stopCharTester)
throws BufferUnderflowException {
return BytesInternal.parse8bit(this, stopCharTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharsTester to check if the end has been reached.
*/
@SuppressWarnings("rawtypes")
@ForceInline
default void parse8bit(Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
if (buffer instanceof StringBuilder)
BytesInternal.parse8bit(this, (StringBuilder) buffer, stopCharsTester);
else
BytesInternal.parse8bit(this, (Bytes) buffer, stopCharsTester);
}
@SuppressWarnings("rawtypes")
default void parse8bit(Bytes buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
BytesInternal.parse8bit(this, buffer, stopCharsTester);
}
default void parse8bit(StringBuilder buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
BytesInternal.parse8bit(this, buffer, stopCharsTester);
}
/**
* parse text as an int. The terminating character is consumed.
*
* @return an int.
*/
@ForceInline
default int parseInt() throws BufferUnderflowException {
return Maths.toInt32(BytesInternal.parseLong(this));
}
/**
* parse text as a long integer. The terminating character is consumed.
*
* @return a long.
*/
@ForceInline
default long parseLong() throws BufferUnderflowException {
return BytesInternal.parseLong(this);
}
/**
* parse text as a float decimal. The terminating character is consumed.
* <p>
* The number of decimal places can be retrieved with lastDecimalPlaces()
*
* @return a float.
*/
default float parseFloat() throws BufferUnderflowException {
return (float) BytesInternal.parseDouble(this);
}
/**
* parse text as a double decimal. The terminating character is consumed.
* <p>
* The number of decimal places can be retrieved with lastDecimalPlaces()
*
* @return a double.
*/
default double parseDouble() throws BufferUnderflowException {
return BytesInternal.parseDouble(this);
}
/**
* Parse the significant digits of a decimal number.
* <p>
* The number of decimal places can be retrieved with lastDecimalPlaces()
*
* @return the significant digits
*/
default long parseLongDecimal() throws BufferUnderflowException {
return BytesInternal.parseLongDecimal(this);
}
/**
* @return the last number of decimal places for parseDouble or parseLongDecimal
*/
int lastDecimalPlaces();
/**
* Store the last number of decimal places. If
*
* @param lastDecimalPlaces set the number of decimal places if positive, otherwise 0.
*/
void lastDecimalPlaces(int lastDecimalPlaces);
/**
* Skip text until a terminating character is reached.
*
* @param tester to stop at
* @return true if a terminating character was found, false if the end of the buffer was reached.
*/
@ForceInline
default boolean skipTo( StopCharTester tester) {
return BytesInternal.skipTo(this, tester);
}
default BigDecimal parseBigDecimal() {
return new BigDecimal(parseUtf8(StopCharTesters.NUMBER_END));
}
}

@ -1,66 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.io.IOException;
import java.io.Reader;
import java.nio.BufferUnderflowException;
/**
* A Reader wrapper for Bytes. This Reader moves the readPosition() of the underlying Bytes up to the readLimit()
*/
@SuppressWarnings("rawtypes")
public class ByteStringReader extends Reader {
private final ByteStringParser in;
public ByteStringReader(ByteStringParser in) {
this.in = in;
}
@Override
public int read() {
return in.readRemaining() > 0 ? in.readUnsignedByte() : -1;
}
@Override
public long skip(long n) throws IOException {
long len = Math.min(in.readRemaining(), n);
try {
in.readSkip(len);
} catch (BufferUnderflowException e) {
throw new IOException(e);
}
return len;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
try {
return in.read(cbuf, off, len);
} catch (BufferUnderflowException e) {
throw new IOException(e);
}
}
@Override
public void close() {
}
}

@ -1,94 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.Writer;
import java.nio.BufferOverflowException;
/**
* A Writer for an underlying Bytes. This moves the writePosition() up to the writeLimit();
*/
@SuppressWarnings("rawtypes")
class ByteStringWriter extends Writer {
private final ByteStringAppender out;
ByteStringWriter(ByteStringAppender out) {
this.out = out;
}
@Override
public void write(int c) throws IOException {
try {
out.append((char) c);
} catch ( BufferOverflowException e) {
throw new IOException(e);
}
}
@Override
public void write( String str) throws IOException {
out.append(str);
}
@Override
public void write( String str, int off, int len) throws IOException {
out.append(str, off, off + len);
}
@Override
public Writer append( CharSequence csq) throws IOException {
out.append(csq);
return this;
}
@Override
public Writer append( CharSequence csq, int start, int end) throws IOException {
out.append(csq, start, end);
return this;
}
@Override
public Writer append(char c) throws IOException {
out.append(c);
return this;
}
@Override
public void flush() {
}
@Override
public void close() {
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
for (int i = 0; i < len; i++)
out.append(cbuf[i + off]);
}
}

@ -1,52 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
/**
* This Interface allows a reference to off heap memory to be reassigned.
* <p></p>
* A reference to off heap memory is a proxy for some memory which sits outside the heap.
*/
public interface Byteable<B extends BytesStore<B, Underlying>, Underlying> {
/**
* This setter for a data type which points to an underlying ByteStore.
*
* @param bytesStore the fix point ByteStore
* @param offset the offset within the ByteStore
* @param length the length in the ByteStore
*/
void bytesStore(BytesStore<B, Underlying> bytesStore, long offset, long length)
throws IllegalStateException, IllegalArgumentException, BufferOverflowException,
BufferUnderflowException;
BytesStore<B, Underlying> bytesStore();
long offset();
/**
* @return the maximum size in byte for this reference.
*/
long maxSize();
}

@ -1,944 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.UsedViaReflection;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.ReferenceOwner;
import net.openhft.chronicle.core.util.ObjectUtils;
import net.openhft.chronicle.core.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
/**
* Bytes is a pointer to a region of memory within a BytesStore. It can be for a fixed region of
* memory or an "elastic" buffer which can be resized, but not for a fixed region. <p></p> This is a
* BytesStore which is mutable and not thread safe. It has a write position and read position which
* must follow these constraints <p></p> start() &lt;= readPosition() &lt;= writePosition() &lt;=
* writeLimit() &lt;= capacity() <p></p> Also readLimit() == writePosition() and readPosition()
* &lt;= safeLimit(); <p></p>
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface Bytes<Underlying> extends
BytesStore<Bytes<Underlying>, Underlying>,
BytesIn<Underlying>,
BytesOut<Underlying> {
long MAX_CAPACITY = Long.MAX_VALUE & ~0xF; // 8 EiB - 16
int MAX_HEAP_CAPACITY = Integer.MAX_VALUE & ~0xF; // 2 GiB - 16
@Deprecated(/* to be removed in x.22 */)
int MAX_BYTE_BUFFER_CAPACITY = MAX_HEAP_CAPACITY;
int DEFAULT_BYTE_BUFFER_CAPACITY = 256;
/**
* Creates and returns a new elastic wrapper for a direct (off-heap) ByteBuffer with a default capacity
* which will be resized as required.
*
* @return a new elastic wrapper for a direct (off-heap) ByteBuffer with a default capacity
* which will be resized as required
*/
static Bytes<ByteBuffer> elasticByteBuffer() {
return elasticByteBuffer(DEFAULT_BYTE_BUFFER_CAPACITY);
}
/**
* Creates and returns a new elastic wrapper for a direct (off-heap) ByteBuffer with
* the given {@code initialCapacity} which will be resized as required.
*
* @param initialCapacity the initial non-negative capacity given in bytes
* @return a new elastic wrapper for a direct (off-heap) ByteBuffer with
* the given {@code initialCapacity} which will be resized as required
*/
static Bytes<ByteBuffer> elasticByteBuffer(int initialCapacity) {
return elasticByteBuffer(initialCapacity, MAX_HEAP_CAPACITY);
}
/**
* Creates and returns a new elastic wrapper for a direct (off-heap) ByteBuffer with
* the given {@code initialCapacity} which will be resized as required up
* to the given {@code maxSize}.
*
* @param initialCapacity the initial non-negative capacity given in bytes
* @param maxCapacity the max capacity given in bytes equal or greater than initialCapacity
* @return a new elastic wrapper for a direct (off-heap) ByteBuffer with
* the given {@code initialCapacity} which will be resized as required up
* to the given {@code maxCapacity}
*/
static Bytes<ByteBuffer> elasticByteBuffer(int initialCapacity, int maxCapacity) {
NativeBytesStore<ByteBuffer> bs = NativeBytesStore.elasticByteBuffer(initialCapacity, maxCapacity);
try {
return bs.bytesForWrite();
} finally {
bs.release(ReferenceOwner.INIT);
}
}
/**
* Creates and returns a new elastic wrapper for a heap ByteBuffer with
* the given {@code initialCapacity} which will be resized as required.
*
* @param initialCapacity the initial non-negative capacity given in bytes
* @return a new elastic wrapper for a heap ByteBuffer with
* the given {@code initialCapacity} which will be resized as required
*/
static Bytes<ByteBuffer> elasticHeapByteBuffer(int initialCapacity) {
HeapBytesStore<ByteBuffer> bs = HeapBytesStore.wrap(ByteBuffer.allocate(initialCapacity));
try {
return NativeBytes.wrapWithNativeBytes(bs, Bytes.MAX_HEAP_CAPACITY);
} finally {
bs.release(INIT);
}
}
static Bytes<ByteBuffer> elasticHeapByteBuffer() {
return elasticHeapByteBuffer(128);
}
/**
* Wrap the ByteBuffer ready for reading
* Method for convenience only - might not be ideal for performance (creates garbage).
* To avoid garbage, use something like this example:
* <pre>{@code
* import net.openhft.chronicle.bytes.Bytes;
* import java.nio.ByteBuffer;
*
* public class ChronicleBytesWithByteBufferExampleTest {
* private static final String HELLO_WORLD = "hello world";
*
* public static void main(String[] args) throws InterruptedException {
* //setup Bytes and ByteBuffer to write from
* Bytes b = Bytes.elasticByteBuffer();
* ByteBuffer toWriteFrom = ByteBuffer.allocate(HELLO_WORLD.length());
* toWriteFrom.put(HELLO_WORLD.getBytes(), 0, HELLO_WORLD.length());
* toWriteFrom.flip();
* byte[] toReadTo = new byte[HELLO_WORLD.length()];
*
* doWrite(b, toWriteFrom);
* ByteBuffer byteBuffer = doRead(b);
*
* //check result
* final StringBuilder sb = new StringBuilder();
* for (int i = 0; i < HELLO_WORLD.length(); i++) {
* sb.append((char) byteBuffer.get());
* }
* assert sb.toString().equals(HELLO_WORLD): "Failed - strings not equal!";
* }
*
* private static void doWrite(Bytes b, ByteBuffer toWrite) {
* //no garbage when writing to Bytes from ByteBuffer
* b.clear();
* b.write(b.writePosition(), toWrite, toWrite.position(), toWrite.limit());
* }
*
* private static ByteBuffer doRead(Bytes b) {
* //no garbage when getting the underlying ByteBuffer
* assert b.underlyingObject() instanceof ByteBuffer;
* ByteBuffer byteBuffer = (ByteBuffer) b.underlyingObject();
* return byteBuffer;
* }
* }
* }</pre>
*
* @param byteBuffer to wrap
* @return a Bytes which wraps the provided ByteBuffer and is ready for reading.
*/
static Bytes<ByteBuffer> wrapForRead( ByteBuffer byteBuffer) {
BytesStore<?, ByteBuffer> bs = BytesStore.wrap(byteBuffer);
try {
Bytes<ByteBuffer> bbb = bs.bytesForRead();
bbb.readLimit(byteBuffer.limit());
bbb.readPosition(byteBuffer.position());
return bbb;
} finally {
bs.release(INIT);
}
}
/**
* Wrap the ByteBuffer ready for writing
* Method for convenience only - might not be ideal for performance (creates garbage).
* To avoid garbage, use something like this example:
* <pre>{@code
* import net.openhft.chronicle.bytes.Bytes;
* import java.nio.ByteBuffer;
*
* public class ChronicleBytesWithByteBufferExampleTest {
* private static final String HELLO_WORLD = "hello world";
*
* public static void main(String[] args) throws InterruptedException {
* //setup Bytes and ByteBuffer to write from
* Bytes b = Bytes.elasticByteBuffer();
* ByteBuffer toWriteFrom = ByteBuffer.allocate(HELLO_WORLD.length());
* toWriteFrom.put(HELLO_WORLD.getBytes(), 0, HELLO_WORLD.length());
* toWriteFrom.flip();
* byte[] toReadTo = new byte[HELLO_WORLD.length()];
*
* doWrite(b, toWriteFrom);
* ByteBuffer byteBuffer = doRead(b);
*
* //check result
* final StringBuilder sb = new StringBuilder();
* for (int i = 0; i < HELLO_WORLD.length(); i++) {
* sb.append((char) byteBuffer.get());
* }
* assert sb.toString().equals(HELLO_WORLD): "Failed - strings not equal!";
* }
*
* private static void doWrite(Bytes b, ByteBuffer toWrite) {
* //no garbage when writing to Bytes from ByteBuffer
* b.clear();
* b.write(b.writePosition(), toWrite, toWrite.position(), toWrite.limit());
* }
*
* private static ByteBuffer doRead(Bytes b) {
* //no garbage when getting the underlying ByteBuffer
* assert b.underlyingObject() instanceof ByteBuffer;
* ByteBuffer byteBuffer = (ByteBuffer) b.underlyingObject();
* return byteBuffer;
* }
* }
* }</pre>
*
* @param byteBuffer to wrap
* @return a Bytes which wraps the provided ByteBuffer and is ready for writing.
*/
static Bytes<ByteBuffer> wrapForWrite( ByteBuffer byteBuffer) {
BytesStore<?, ByteBuffer> bs = BytesStore.wrap(byteBuffer);
try {
Bytes<ByteBuffer> bbb = bs.bytesForWrite();
bbb.writePosition(byteBuffer.position());
bbb.writeLimit(byteBuffer.limit());
return bbb;
} finally {
bs.release(INIT);
}
}
/**
* Wrap the byte[] ready for reading
* Method for convenience only - might not be ideal for performance (creates garbage).
* To avoid garbage, use something like this example:
* <pre>{@code
* import net.openhft.chronicle.bytes.Bytes;
* import java.nio.charset.Charset;
*
* public class ChronicleBytesWithPrimByteArrayExampleTest {
* private static final Charset ISO_8859 = Charset.forName("ISO-8859-1");
* private static final String HELLO_WORLD = "hello world";
*
* public static void main(String[] args) {
* //setup Bytes and byte[]s to write from and read to
* Bytes b = Bytes.elasticByteBuffer();
* byte[] toWriteFrom = HELLO_WORLD.getBytes(ISO_8859);
* byte[] toReadTo = new byte[HELLO_WORLD.length()];
*
* doWrite(b, toWriteFrom);
* doRead(b, toReadTo);
*
* //check result
* final StringBuilder sb = new StringBuilder();
* for (int i = 0; i < HELLO_WORLD.length(); i++) {
* sb.append((char) toReadTo[i]);
* }
* assert sb.toString().equals(HELLO_WORLD): "Failed - strings not equal!";
* }
*
* private static void doWrite(Bytes b, byte[] toWrite) {
* //no garbage when writing to Bytes from byte[]
* b.clear();
* b.write(toWrite);
* }
*
* private static void doRead(Bytes b, byte[] toReadTo) {
* //no garbage when reading from Bytes into byte[]
* b.read( toReadTo, 0, HELLO_WORLD.length());
* }
* }
* }</pre>
*
* @param byteArray to wrap
* @return the Bytes ready for reading.
*/
static Bytes<byte[]> wrapForRead( byte[] byteArray) {
HeapBytesStore<byte[]> bs = BytesStore.wrap(byteArray);
try {
return bs.bytesForRead();
} finally {
bs.release(INIT);
}
}
/**
* Wrap the byte[] ready for writing
* Method for convenience only - might not be ideal for performance (creates garbage).
* To avoid garbage, use something like this example:
* <pre>{@code
* import net.openhft.chronicle.bytes.Bytes;
* import java.nio.charset.Charset;
*
* public class ChronicleBytesWithPrimByteArrayExampleTest {
* private static final Charset ISO_8859 = Charset.forName("ISO-8859-1");
* private static final String HELLO_WORLD = "hello world";
*
* public static void main(String[] args) {
* //setup Bytes and byte[]s to write from and read to
* Bytes b = Bytes.elasticByteBuffer();
* byte[] toWriteFrom = HELLO_WORLD.getBytes(ISO_8859);
* byte[] toReadTo = new byte[HELLO_WORLD.length()];
*
* doWrite(b, toWriteFrom);
* doRead(b, toReadTo);
*
* //check result
* final StringBuilder sb = new StringBuilder();
* for (int i = 0; i < HELLO_WORLD.length(); i++) {
* sb.append((char) toReadTo[i]);
* }
* assert sb.toString().equals(HELLO_WORLD): "Failed - strings not equal!";
* }
*
* private static void doWrite(Bytes b, byte[] toWrite) {
* //no garbage when writing to Bytes from byte[]
* b.clear();
* b.write(toWrite);
* }
*
* private static void doRead(Bytes b, byte[] toReadTo) {
* //no garbage when reading from Bytes into byte[]
* b.read( toReadTo, 0, HELLO_WORLD.length());
* }
* }
* }</pre>
*
* @param byteArray to wrap
* @return the Bytes ready for writing.
*/
static Bytes<byte[]> wrapForWrite( byte[] byteArray) {
BytesStore bs = BytesStore.wrap(byteArray);
try {
return bs.bytesForWrite();
} finally {
bs.release(INIT);
}
}
/**
* Convert text to bytes using ISO-8859-1 encoding and return a Bytes ready for reading.
* <p>
* Note: this returns a direct Bytes now
*
* @param text to convert
* @return Bytes ready for reading.
*/
static Bytes<?> from( CharSequence text) {
return from(text.toString());
}
@Deprecated(/* to be removed in x.22 */)
static Bytes<?> fromString(String text) {
return from(text);
}
/**
* Convert text to bytes using ISO-8859-1 encoding and return a Bytes ready for reading.
* <p>
* Note: this returns a direct Bytes now
*
* @param text to convert
* @return Bytes ready for reading.
*/
static Bytes<?> directFrom( String text) {
NativeBytesStore from = NativeBytesStore.from(text);
try {
return from.bytesForRead();
} finally {
from.release(INIT);
}
}
/**
* Convert text to bytes using ISO-8859-1 encoding and return a Bytes ready for reading.
* <p>
* Note: this returns a heap Bytes
*
* @param text to convert
* @return Bytes ready for reading.
*/
static Bytes<byte[]> from( String text) throws IllegalArgumentException, IllegalStateException {
return wrapForRead(text.getBytes(StandardCharsets.ISO_8859_1));
}
@UsedViaReflection
static Bytes<byte[]> valueOf(String text) {
return from(text);
}
/**
* Creates and returns a new fix sized wrapper for native (64-bit address)
* memory with the given {@code capacity}.
*
* @param capacity the non-negative capacity given in bytes
* @return a new fix sized wrapper for native (64-bit address)
* memory with the given {@code capacity}
*/
static VanillaBytes<Void> allocateDirect(long capacity) throws IllegalArgumentException {
NativeBytesStore<Void> bs = NativeBytesStore.nativeStoreWithFixedCapacity(capacity);
try {
return new VanillaBytes<>(bs);
} finally {
bs.release(INIT);
}
}
/**
* Creates and returns a new elastic wrapper for native (64-bit address)
* memory with zero initial capacity which will be resized as required.
*
* @return a new elastic wrapper for native (64-bit address)
* memory with zero initial capacity which will be resized as required
*/
static NativeBytes<Void> allocateElasticDirect() {
return NativeBytes.nativeBytes();
}
/**
* Creates and returns a new elastic wrapper for native (64-bit address)
* memory with the given {@code initialCapacity} which will be resized as required.
*
* @param initialCapacity the initial non-negative capacity given in bytes
* @return a new elastic wrapper for native (64-bit address)
* memory with the given {@code initialCapacity} which will be resized as required
*/
static NativeBytes<Void> allocateElasticDirect(long initialCapacity) throws IllegalArgumentException {
return NativeBytes.nativeBytes(initialCapacity);
}
static OnHeapBytes allocateElasticOnHeap() {
return allocateElasticOnHeap(32);
}
static OnHeapBytes allocateElasticOnHeap(int initialCapacity) {
HeapBytesStore<byte[]> wrap = HeapBytesStore.wrap(new byte[initialCapacity]);
try {
return new OnHeapBytes(wrap, true);
} finally {
wrap.release(INIT);
}
}
/**
* Creates a string from the {@code position} to the {@code limit}, The buffer is not modified
* by this call
*
* @param buffer the buffer to use
* @return a string contain the text from the {@code position} to the {@code limit}
*/
static String toString( final Bytes<?> buffer) throws BufferUnderflowException {
return toString(buffer, MAX_HEAP_CAPACITY);
}
/**
* Creates a string from the {@code position} to the {@code limit}, The buffer is not modified
* by this call
*
* @param buffer the buffer to use
* @param maxLen of the result returned
* @return a string contain the text from the {@code position} to the {@code limit}
*/
static String toString( final Bytes<?> buffer, long maxLen) throws
BufferUnderflowException {
if (buffer.refCount() < 1)
// added because something is crashing the JVM
return "<unknown>";
ReferenceOwner toString = ReferenceOwner.temporary("toString");
buffer.reserve(toString);
try {
if (buffer.readRemaining() == 0)
return "";
final long length = Math.min(maxLen + 1, buffer.readRemaining());
final StringBuilder builder = new StringBuilder();
try {
buffer.readWithLength(length, b -> {
while (buffer.readRemaining() > 0) {
if (builder.length() >= maxLen) {
builder.append("...");
break;
}
builder.append((char) buffer.readByte());
}
});
} catch (Exception e) {
builder.append(' ').append(e);
}
return builder.toString();
} finally {
buffer.release(toString);
}
}
/**
* The buffer is not modified by this call
*
* @param buffer the buffer to use
* @param position the position to create the string from
* @param len the number of characters to show in the string
* @return a string contain the text from offset {@code position}
*/
static String toString( final Bytes buffer, long position, long len)
throws BufferUnderflowException {
final long pos = buffer.readPosition();
final long limit = buffer.readLimit();
buffer.readPositionRemaining(position, len);
try {
final StringBuilder builder = new StringBuilder();
while (buffer.readRemaining() > 0) {
builder.append((char) buffer.readByte());
}
// remove the last comma
return builder.toString();
} finally {
buffer.readLimit(limit);
buffer.readPosition(pos);
}
}
/**
* Creates and returns a new fix sized wrapper for native (64-bit address)
* memory with the contents copied from the given {@code bytes} array.
* <p>
* Changes in the given {@code bytes} will not be affected by writes in
* the returned wrapper or vice versa.
*
* @param bytes array to copy
* @return a new fix sized wrapper for native (64-bit address)
* memory with the contents copied from the given {@code bytes} array
*/
static VanillaBytes allocateDirect( byte[] bytes) throws IllegalArgumentException {
VanillaBytes<Void> result = allocateDirect(bytes.length);
try {
result.write(bytes);
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
return result;
}
static Bytes fromHexString( String s) {
return BytesInternal.fromHexString(s);
}
/**
* Code shared by String and StringBuffer to do searches. The
* source is the character array being searched, and the target
* is the string being searched for.
*
* @param source the read bytes being searched.
* @param target the read bytes being searched for.
* @param fromIndex the index to begin searching from,
* @return the index of where the text was found.
*/
static int indexOf( BytesStore source, BytesStore target, int fromIndex) {
long sourceOffset = source.readPosition();
long targetOffset = target.readPosition();
long sourceCount = source.readRemaining();
long targetCount = target.readRemaining();
if (fromIndex >= sourceCount) {
return Math.toIntExact(targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
byte firstByte = target.readByte(targetOffset);
long max = sourceOffset + (sourceCount - targetCount);
for (long i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source.readByte(i) != firstByte) {
while (++i <= max && source.readByte(i) != firstByte) ;
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
long j = i + 1;
long end = j + targetCount - 1;
for (long k = targetOffset + 1; j < end && source.readByte(j) == target.readByte(k); j++, k++) {
}
if (j == end) {
/* Found whole string. */
return Math.toIntExact(i - sourceOffset);
}
}
}
return -1;
}
/**
* Return a Bytes which is optionally unchecked. This allows bounds checks to be turned off.
* Note: this means that the result is no longer elastic, even if <code>this</code> is elastic.
*
* @param unchecked if true, minimal bounds checks will be performed.
* @return Bytes without bounds checking.
* @throws IllegalStateException if the underlying BytesStore has been released
*/
default Bytes<Underlying> unchecked(boolean unchecked) throws IllegalStateException {
if (unchecked) {
if (isElastic())
BytesUtil.WarnUncheckedElasticBytes.warn();
Bytes<Underlying> underlyingBytes = start() == 0 && bytesStore().isDirectMemory() ?
new UncheckedNativeBytes<>(this) :
new UncheckedBytes<>(this);
release(INIT);
return underlyingBytes;
}
return this;
}
default boolean unchecked() {
return false;
}
/**
* @inheritDoc <P>
* If this Bytes {@link #isElastic()} the {@link #safeLimit()} can be
* lower than the point it can safely write.
*/
@Override
default long safeLimit() {
return bytesStore().safeLimit();
}
@Override
default boolean isClear() {
return start() == readPosition() && writeLimit() == capacity();
}
/**
* @inheritDoc <P>
* If this Bytes {@link #isElastic()} the {@link #realCapacity()} can be
* lower than the virtual {@link #capacity()}.
*/
@Override
default long realCapacity() {
return BytesStore.super.realCapacity();
}
/**
* @return a copy of this Bytes from position() to limit().
*/
@Override
BytesStore<Bytes<Underlying>, Underlying> copy();
default String toHexString() {
return toHexString(1024);
}
/**
* display the hex data of {@link Bytes} from the position() to the limit()
*
* @param maxLength limit the number of bytes to be dumped.
* @return hex representation of the buffer, from example [0D ,OA, FF]
*/
default String toHexString(long maxLength) {
return toHexString(readPosition(), maxLength);
}
/**
* display the hex data of {@link Bytes} from the position() to the limit()
*
* @param maxLength limit the number of bytes to be dumped.
* @return hex representation of the buffer, from example [0D ,OA, FF]
*/
default String toHexString(long offset, long maxLength) {
// if (Jvm.isDebug() && Jvm.stackTraceEndsWith("Bytes", 3))
// return "Not Available";
long maxLength2 = Math.min(maxLength, readLimit() - offset);
String ret = BytesInternal.toHexString(this, offset, maxLength2);
return maxLength2 < readLimit() - offset ? ret + "... truncated" : ret;
}
/**
* Returns if this Bytes is elastic. I.e. it can resize when more data is written
* than it's {@link #realCapacity()}.
*
* @return if this Bytes is elastic
*/
boolean isElastic();
/**
* grow the buffer if the buffer is elastic, if the buffer is not elastic and there is not
* enough capacity then this method will throws {@link java.nio.BufferOverflowException}
*
* @param size the capacity that you required
* @throws IllegalArgumentException if the buffer is not elastic and there is not enough space
*/
default void ensureCapacity(long size) throws IllegalArgumentException {
if (size > capacity())
throw new IllegalArgumentException(isElastic() ? "todo" : "not elastic");
}
/**
* Creates a slice of the current Bytes based on its position() and limit(). As a sub-section
* of a Bytes it cannot be elastic.
*
* @return a slice of the existing Bytes where the start is moved to the position and the
* current limit determines the capacity.
* @throws IllegalStateException if the underlying BytesStore has been released
*/
@Override
default Bytes<Underlying> bytesForRead() throws IllegalStateException {
return isClear() ? BytesStore.super.bytesForRead() : new SubBytes<>(this, readPosition(), readLimit() + start());
}
/**
* @return the ByteStore this Bytes wraps.
*/
@Override
BytesStore bytesStore();
default boolean isEqual(String s) {
return StringUtils.isEqual(this, s);
}
/**
* Compact these Bytes by moving the readPosition to the start.
*
* @return this
*/
Bytes<Underlying> compact();
/**
* copy bytes from one ByteStore to another
*
* @param store to copy to
* @return the number of bytes copied.
*/
@Override
default long copyTo( BytesStore store) {
return BytesStore.super.copyTo(store);
}
@Override
default void copyTo( OutputStream out) throws IOException {
BytesStore.super.copyTo(out);
}
@Override
default boolean sharedMemory() {
return bytesStore().sharedMemory();
}
/**
* will unwrite from the offset upto the current write position of the destination bytes
*
* @param fromOffset the offset from the target byytes
* @param count the number of bytes to un-write
*/
default void unwrite(long fromOffset, int count) {
long wp = writePosition();
if (wp < fromOffset)
return;
write(fromOffset, this, fromOffset + count, wp - fromOffset - count);
writeSkip(-count);
}
default BigDecimal readBigDecimal() {
return new BigDecimal(readBigInteger(), Maths.toUInt31(readStopBit()));
}
default BigInteger readBigInteger() {
int length = Maths.toUInt31(readStopBit());
if (length == 0)
if (lenient())
return BigInteger.ZERO;
else
throw new BufferUnderflowException();
byte[] bytes = new byte[length];
read(bytes);
return new BigInteger(bytes);
}
/**
* Returns the index within this bytes of the first occurrence of the
* specified sub-bytes.
* <p>
* <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre>
* this.startsWith(bytes, <i>k</i>)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned.
*
* @param source the sub-bytes to search for.
* @return the index of the first occurrence of the specified sub-bytes,
* or {@code -1} if there is no such occurrence.
*/
default long indexOf( Bytes source) {
return indexOf(source, 0);
}
/**
* Returns the index within this bytes of the first occurrence of the
* specified subbytes.
* <p>
* <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre>
* this.startsWith(bytes, <i>k</i>)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then {@code -1} is returned.
*
* @param source the sub-bytes to search for.
* @param fromIndex start the seach from this offset
* @return the index of the first occurrence of the specified sub-bytes,
* or {@code -1} if there is no such occurrence.
*/
default int indexOf( BytesStore source, int fromIndex) {
return indexOf(this, source, fromIndex);
}
@Deprecated(/* to be removed in x.22 */)
default long indexOf( Bytes source, int fromIndex) {
return indexOf(this, source, fromIndex);
}
@Override
Bytes<Underlying> clear();
@Override
default boolean readWrite() {
return bytesStore().readWrite();
}
default void readWithLength(long length, BytesOut<Underlying> bytesOut)
throws BufferUnderflowException, IORuntimeException {
if (length > readRemaining())
throw new BufferUnderflowException();
long limit0 = readLimit();
long limit = readPosition() + length;
boolean lenient = lenient();
try {
lenient(true);
readLimit(limit);
bytesOut.write(this);
} finally {
readLimit(limit0);
readPosition(limit);
lenient(lenient);
}
}
default <T extends ReadBytesMarshallable> T readMarshallableLength16(Class<T> tClass, T object) {
if (object == null) object = ObjectUtils.newInstance(tClass);
int length = readUnsignedShort();
long limit = readLimit();
long end = readPosition() + length;
boolean lenient = lenient();
try {
lenient(true);
readLimit(end);
object.readMarshallable(this);
} finally {
readPosition(end);
readLimit(limit);
lenient(lenient);
}
return object;
}
default void writeMarshallableLength16(WriteBytesMarshallable marshallable) {
long position = writePosition();
writeUnsignedShort(0);
marshallable.writeMarshallable(this);
long length = writePosition() - position - 2;
if (length >= 1 << 16)
throw new IllegalStateException("Marshallable " + marshallable.getClass() + " too long was " + length);
writeUnsignedShort(position, (int) length);
}
default Bytes write(final InputStream inputStream) throws IOException {
for (; ; ) {
int read;
read = inputStream.read();
if (read == -1)
break;
writeByte((byte) read);
}
return this;
}
}

@ -1,51 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
public interface BytesComment<B extends BytesComment<B>> {
/**
* Do these Bytes support saving comments
*
* @return true if comments are kept
*/
default boolean retainsComments() {
return false;
}
/**
* Add comment as approriate for the toHexString format
*
* @param comment to add (or ignore)
* @return this
*/
@SuppressWarnings("unchecked")
default B comment(CharSequence comment) {
return (B) this;
}
/**
* Adjust the indent for nested data
*
* @param n +1 indent in, -1 reduce indenting
* @return this.
*/
@SuppressWarnings("unchecked")
default B indent(int n) {
return (B) this;
}
}

@ -1,36 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.nio.BufferOverflowException;
@FunctionalInterface
public interface BytesConsumer {
/**
* Retrieves and removes the head of this queue, or returns {@code true} if this queue is
* empty.
*
* @param bytes to read into
* @return false if this queue is empty
*/
@SuppressWarnings("rawtypes")
boolean read(BytesOut bytes) throws BufferOverflowException;
}

@ -1,42 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
public interface BytesContext extends Closeable {
/**
* @return a bytes to write to
*/
@SuppressWarnings("rawtypes")
Bytes bytes();
/**
* @return the key to be written to
*/
int key();
@Override
default boolean isClosed() {
throw new UnsupportedOperationException("todo");
}
default void rollbackOnClose() {
}
}

@ -1,76 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings({"rawtypes", "unchecked"})
public interface BytesIn<Underlying> extends
RandomDataInput,
ByteStringParser<Bytes<Underlying>> {
/**
* Reads messages from this tails as methods. It returns a BooleanSupplier which returns
*
* @param objects which implement the methods serialized to the file.
* @return a reader which will read one Excerpt at a time
*/
default MethodReader bytesMethodReader(Object... objects) {
return new BytesMethodReaderBuilder(this).build(objects);
}
default BytesMethodReaderBuilder bytesMethodReaderBuilder() {
return new BytesMethodReaderBuilder(this);
}
<T extends ReadBytesMarshallable> T readMarshallableLength16(Class<T> tClass, T object);
default <T> T readObject(Class<T> componentType0) {
Class<T> componentType = ObjectUtils.implementationToUse(componentType0);
if (BytesMarshallable.class.isAssignableFrom(componentType)) {
BytesMarshallable bm = (BytesMarshallable) ObjectUtils.newInstance(componentType);
bm.readMarshallable(this);
return (T) bm;
}
if (Enum.class.isAssignableFrom(componentType)) {
return (T) readEnum((Class) componentType);
}
switch (componentType.getName()) {
case "java.lang.String":
return (T) readUtf8();
case "java.lang.Double":
return (T) (Double) readDouble();
case "java.lang.Long":
return (T) (Long) readLong();
case "java.lang.Integer":
return (T) (Integer) readInt();
default:
if (BytesMarshallable.class.isAssignableFrom(componentType)) {
BytesMarshallable bm = (BytesMarshallable) ObjectUtils.newInstance(componentType);
bm.readMarshallable(this);
return (T) bm;
}
throw new UnsupportedOperationException("Unsupported " + componentType);
}
}
}

@ -1,48 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.annotation.DontChain;
import net.openhft.chronicle.core.io.IORuntimeException;
/**
* An object which can be read or written directly to Bytes in a streaming manner.
*/
@DontChain
public interface BytesMarshallable extends ReadBytesMarshallable, WriteBytesMarshallable {
@Override
@SuppressWarnings("rawtypes")
default void readMarshallable(BytesIn bytes) throws IORuntimeException {
BytesUtil.readMarshallable(this, bytes);
}
@SuppressWarnings("rawtypes")
@Override
default void writeMarshallable(BytesOut bytes) {
BytesUtil.writeMarshallable(this, bytes);
}
default String $toString() {
HexDumpBytes bytes = new HexDumpBytes();
writeMarshallable(bytes);
String s = "# " + getClass().getName() + "\n" + bytes.toHexString();
bytes.releaseLast();
return s;
}
}

@ -1,759 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.ClassLocal;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.Supplier;
@SuppressWarnings({"rawtypes", "unchecked"})
public class BytesMarshaller<T> {
public static final ClassLocal<BytesMarshaller> BYTES_MARSHALLER_CL
= ClassLocal.withInitial(BytesMarshaller::new);
private final FieldAccess[] fields;
public BytesMarshaller( Class<T> tClass) {
Map<String, Field> map = new LinkedHashMap<>();
getAllField(tClass, map);
fields = map.values().stream()
.map(FieldAccess::create).toArray(FieldAccess[]::new);
}
public static void getAllField( Class clazz, Map<String, Field> map) {
if (clazz != Object.class)
getAllField(clazz.getSuperclass(), map);
for ( Field field : clazz.getDeclaredFields()) {
if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0)
continue;
Jvm.setAccessible(field);
map.put(field.getName(), field);
}
}
public void readMarshallable(ReadBytesMarshallable t, BytesIn in) {
for ( FieldAccess field : fields) {
field.read(t, in);
}
}
public void writeMarshallable(WriteBytesMarshallable t, BytesOut out) {
out.indent(+1);
for ( FieldAccess field : fields) {
field.write(t, out);
}
out.indent(-1);
}
static abstract class FieldAccess<T> {
final Field field;
FieldAccess(Field field) {
this.field = field;
}
public static Object create( Field field) {
Class<?> type = field.getType();
switch (type.getName()) {
case "boolean":
return new BooleanFieldAccess(field);
case "byte":
return new ByteFieldAccess(field);
case "char":
return new CharFieldAccess(field);
case "short":
return new ShortFieldAccess(field);
case "int":
return new IntegerFieldAccess(field);
case "float":
return new FloatFieldAccess(field);
case "long":
return new LongFieldAccess(field);
case "double":
return new DoubleFieldAccess(field);
default:
if (type.isArray()) {
if (type.getComponentType().isPrimitive()) {
if (type == byte[].class)
return new ByteArrayFieldAccess(field);
if (type == int[].class)
return new IntArrayFieldAccess(field);
if (type == float[].class)
return new FloatArrayFieldAccess(field);
if (type == long[].class)
return new LongArrayFieldAccess(field);
if (type == double[].class)
return new DoubleArrayFieldAccess(field);
throw new UnsupportedOperationException("TODO " + field.getType());
}
return new ObjectArrayFieldAccess(field);
}
if (Collection.class.isAssignableFrom(type))
return new CollectionFieldAccess(field);
if (Map.class.isAssignableFrom(type))
return new MapFieldAccess(field);
if (BytesStore.class.isAssignableFrom(type))
return new BytesFieldAccess(field);
if (BytesMarshallable.class.isAssignableFrom(type))
return new BytesMarshallableFieldAccess(field);
return new ScalarFieldAccess(field);
}
}
static Class extractClass(Type type0) {
if (type0 instanceof Class)
return (Class) type0;
else if (type0 instanceof ParameterizedType)
return (Class) ((ParameterizedType) type0).getRawType();
else
return Object.class;
}
@Override
public String toString() {
return getClass().getSimpleName() + "{" +
"field=" + field +
'}';
}
void write(Object o, BytesOut write) {
try {
write.comment(field.getName());
getValue(o, write);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
protected abstract void getValue(Object o, BytesOut write) throws IllegalAccessException;
void read(Object o, BytesIn read) {
try {
setValue(o, read);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
} catch (IORuntimeException e) {
throw Jvm.rethrow(e);
}
}
protected abstract void setValue(Object o, BytesIn read) throws IllegalAccessException, IORuntimeException;
protected Supplier<Map> newInstance( Class type) {
try {
return (Supplier<Map>) type.newInstance();
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} catch (InstantiationException e) {
throw Jvm.rethrow(e);
}
}
}
static class ScalarFieldAccess extends FieldAccess<Object> {
public ScalarFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
Object o2 = field.get(o);
String s = o2 == null ? null : o2.toString();
write.writeUtf8(s);
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException, IORuntimeException {
String s = read.readUtf8();
field.set(o, ObjectUtils.convertTo(field.getType(), s));
}
}
static class BytesMarshallableFieldAccess extends FieldAccess<Object> {
public BytesMarshallableFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
BytesMarshallable o2 = (BytesMarshallable) field.get(o);
assert o2 != null;
o2.writeMarshallable(write);
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException, IORuntimeException {
BytesMarshallable o2 = (BytesMarshallable) field.get(o);
if (!field.getType().isInstance(o2))
field.set(o, o2 = (BytesMarshallable) ObjectUtils.newInstance((Class) field.getType()));
o2.readMarshallable(read);
}
}
static class BytesFieldAccess extends FieldAccess<Bytes> {
public BytesFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
BytesStore bytes = (BytesStore) field.get(o);
if (bytes == null) {
write.writeStopBit(-1);
return;
}
long offset = bytes.readPosition();
long length = bytes.readRemaining();
write.writeStopBit(length);
write.write(bytes, offset, length);
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException, IORuntimeException {
Bytes bytes = (Bytes) field.get(o);
long stopBit = read.readStopBit();
if (stopBit == -1) {
if (bytes != null)
bytes.releaseLast();
field.set(o, null);
return;
}
int length = Maths.toUInt31(stopBit);
Bytes bs;
if (bytes == null) {
bs = Bytes.allocateElasticOnHeap(length);
field.set(o, bs);
} else {
bs = bytes;
}
bs.clear();
read.read(bs, length);
bs.readLimit(length);
}
}
/*
static class ArrayFieldAccess extends FieldAccess {
private final Class componentType;
public ArrayFieldAccess( Field field) {
super(field);
componentType = field.getType().getComponentType();
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
throw new UnsupportedOperationException("TODO");
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
throw new UnsupportedOperationException("TODO");
}
}
*/
static class ObjectArrayFieldAccess extends FieldAccess {
Class componentType;
public ObjectArrayFieldAccess(Field field) {
super(field);
componentType = field.getType().getComponentType();
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
Object[] c = (Object[]) field.get(o);
if (c == null) {
write.writeStopBit(-1);
return;
}
int size = c.length;
write.writeStopBit(size);
if (size == 0)
return;
for (int i = 0; i < size; i++)
write.writeObject(componentType, c[i]);
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
Object[] c = (Object[]) field.get(o);
int length = Maths.toInt32(read.readStopBit());
if (length < 0) {
if (c != null)
field.set(o, null);
return;
}
if (c == null)
field.set(o, c = (Object[]) Array.newInstance(field.getType().getComponentType(), length));
else if (c.length != length)
field.set(o, c = Arrays.copyOf(c, length));
for (int i = 0; i < length; i++) {
Object o2 = c[i];
if (o2 instanceof BytesMarshallable)
((BytesMarshallable) o2).readMarshallable(read);
else
c[i] = read.readObject(componentType);
}
}
}
static class CollectionFieldAccess extends FieldAccess {
final Supplier<Collection> collectionSupplier;
private final Class componentType;
private final Class<?> type;
public CollectionFieldAccess( Field field) {
super(field);
type = field.getType();
if (type == List.class || type == Collection.class)
collectionSupplier = ArrayList::new;
else if (type == SortedSet.class || type == NavigableSet.class)
collectionSupplier = TreeSet::new;
else if (type == Set.class)
collectionSupplier = LinkedHashSet::new;
else
collectionSupplier = newInstance(type);
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) genericType;
Type type0 = pType.getActualTypeArguments()[0];
componentType = extractClass(type0);
} else {
componentType = Object.class;
}
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
Collection c = (Collection) field.get(o);
if (c == null) {
write.writeStopBit(-1);
return;
}
write.writeStopBit(c.size());
if (c.isEmpty())
return;
if (c instanceof RandomAccess && c instanceof List) {
List l = (List) c;
for (int i = 0, size = l.size(); i < size; i++)
write.writeObject(componentType, l.get(i));
} else {
for (Object o2 : c) {
write.writeObject(componentType, o2);
}
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
Collection c = (Collection) field.get(o);
int length = Maths.toInt32(read.readStopBit());
if (length < 0) {
if (c != null)
field.set(o, null);
return;
}
c.clear();
for (int i = 0; i < length; i++)
c.add(read.readObject(componentType));
}
}
static class MapFieldAccess extends FieldAccess {
final Supplier<Map> collectionSupplier;
private final Class<?> type;
private final Class keyType;
private final Class valueType;
public MapFieldAccess( Field field) {
super(field);
type = field.getType();
if (type == Map.class)
collectionSupplier = LinkedHashMap::new;
else if (type == SortedMap.class || type == NavigableMap.class)
collectionSupplier = TreeMap::new;
else
collectionSupplier = newInstance(type);
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) genericType;
Type[] actualTypeArguments = pType.getActualTypeArguments();
keyType = extractClass(actualTypeArguments[0]);
valueType = extractClass(actualTypeArguments[1]);
} else {
keyType = Object.class;
valueType = Object.class;
}
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
Map<?, ?> m = (Map) field.get(o);
if (m == null) {
write.writeStopBit(-1);
return;
}
write.writeStopBit(m.size());
for (Map.Entry<?, ?> entry : m.entrySet()) {
write.writeObject(keyType, entry.getKey());
write.writeObject(valueType, entry.getValue());
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
Map m = (Map) field.get(o);
long length = read.readStopBit();
if (length < 0) {
if (m != null)
field.set(o, null);
return;
}
if (m == null) {
field.set(o, m = new LinkedHashMap<>());
} else {
m.clear();
}
for (int i = 0; i < length; i++) {
m.put(read.readObject(keyType), read.readObject(valueType));
}
}
}
static class BooleanFieldAccess extends FieldAccess {
public BooleanFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeBoolean(field.getBoolean(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setBoolean(o, read.readBoolean());
}
}
static class ByteFieldAccess extends FieldAccess {
public ByteFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeByte(field.getByte(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setByte(o, read.readByte());
}
}
static class ByteArrayFieldAccess extends FieldAccess {
public ByteArrayFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
byte[] array = (byte[]) field.get(o);
if (array == null) {
write.writeInt(~0);
} else {
write.writeInt(array.length);
for (int i = 0; i < array.length; i++)
write.writeByte(array[i]);
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
int len = read.readInt();
if (len == ~0) {
field.set(o, null);
} else if (len >= 0) {
byte[] array = (byte[]) field.get(o);
if (array == null || array.length != len) {
array = new byte[len];
field.set(o, array);
}
for (int i = 0; i < len; i++)
array[i] = read.readByte();
}
}
}
static class CharFieldAccess extends FieldAccess {
public CharFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
char aChar = field.getChar(o);
if (aChar >= 65536 - 127)
write.writeStopBit(aChar - 65536);
else
write.writeStopBit(aChar);
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setChar(o, read.readStopBitChar());
}
}
static class ShortFieldAccess extends FieldAccess {
public ShortFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeShort(field.getShort(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setShort(o, read.readShort());
}
}
static class IntegerFieldAccess extends FieldAccess {
public IntegerFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeInt(field.getInt(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setInt(o, read.readInt());
}
}
static class IntArrayFieldAccess extends FieldAccess {
public IntArrayFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
int[] array = (int[]) field.get(o);
if (array == null) {
write.writeInt(~0);
} else {
write.writeInt(array.length);
for (int i = 0; i < array.length; i++)
write.writeInt(array[i]);
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
int len = read.readInt();
if (len == ~0) {
field.set(o, null);
} else if (len >= 0) {
int[] array = (int[]) field.get(o);
if (array == null || array.length != len) {
array = new int[len];
field.set(o, array);
}
for (int i = 0; i < len; i++)
array[i] = read.readInt();
}
}
}
static class FloatFieldAccess extends FieldAccess {
public FloatFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeFloat(field.getFloat(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setFloat(o, read.readFloat());
}
}
static class FloatArrayFieldAccess extends FieldAccess {
public FloatArrayFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
float[] array = (float[]) field.get(o);
if (array == null) {
write.writeInt(~0);
} else {
write.writeInt(array.length);
for (int i = 0; i < array.length; i++)
write.writeFloat(array[i]);
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
int len = read.readInt();
if (len == ~0) {
field.set(o, null);
} else if (len >= 0) {
float[] array = (float[]) field.get(o);
if (array == null || array.length != len) {
array = new float[len];
field.set(o, array);
}
for (int i = 0; i < len; i++)
array[i] = read.readFloat();
}
}
}
static class LongFieldAccess extends FieldAccess {
public LongFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeLong(field.getLong(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setLong(o, read.readLong());
}
}
static class LongArrayFieldAccess extends FieldAccess {
public LongArrayFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
long[] array = (long[]) field.get(o);
if (array == null) {
write.writeInt(~0);
} else {
write.writeInt(array.length);
for (int i = 0; i < array.length; i++)
write.writeLong(array[i]);
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
int len = read.readInt();
if (len == ~0) {
field.set(o, null);
} else if (len >= 0) {
long[] array = (long[]) field.get(o);
if (array == null || array.length != len) {
array = new long[len];
field.set(o, array);
}
for (int i = 0; i < len; i++)
array[i] = read.readLong();
}
}
}
static class DoubleFieldAccess extends FieldAccess {
public DoubleFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
write.writeDouble(field.getDouble(o));
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
field.setDouble(o, read.readDouble());
}
}
static class DoubleArrayFieldAccess extends FieldAccess {
public DoubleArrayFieldAccess(Field field) {
super(field);
}
@Override
protected void getValue(Object o, BytesOut write) throws IllegalAccessException {
double[] array = (double[]) field.get(o);
if (array == null) {
write.writeInt(~0);
} else {
write.writeInt(array.length);
for (int i = 0; i < array.length; i++)
write.writeDouble(array[i]);
}
}
@Override
protected void setValue(Object o, BytesIn read) throws IllegalAccessException {
int len = read.readInt();
if (len == ~0) {
field.set(o, null);
} else if (len >= 0) {
double[] array = (double[]) field.get(o);
if (array == null || array.length != len) {
array = new double[len];
field.set(o, array);
}
for (int i = 0; i < len; i++)
array[i] = read.readDouble();
}
}
}
}

@ -1,94 +0,0 @@
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.io.SimpleCloseable;
import net.openhft.chronicle.core.util.InvocationTargetRuntimeException;
import net.openhft.chronicle.core.util.ObjectUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Consumer;
@SuppressWarnings("rawtypes")
public class BytesMethodReader extends SimpleCloseable implements MethodReader {
private final BytesIn in;
private final BytesParselet defaultParselet;
private final List<Consumer<BytesIn>> methodEncoders = new ArrayList<>();
private final Map<Long, Consumer<BytesIn>> methodEncoderMap = new LinkedHashMap<>();
public BytesMethodReader(BytesIn in,
BytesParselet defaultParselet,
MethodEncoderLookup methodEncoderLookup,
Object[] objects) {
this.in = in;
this.defaultParselet = defaultParselet;
for (Object object : objects) {
for (Method method : object.getClass().getMethods()) {
MethodEncoder encoder = methodEncoderLookup.apply(method);
if (encoder != null) {
addEncoder(object, method, encoder);
}
}
}
}
private void addEncoder(Object object, Method method, MethodEncoder encoder) {
Jvm.setAccessible(method);
Class<?>[] parameterTypes = method.getParameterTypes();
int count = parameterTypes.length;
BytesMarshallable[][] array = new BytesMarshallable[1][count];
for (int i = 0; i < count; i++) {
array[0][i] = (BytesMarshallable) ObjectUtils.newInstance(parameterTypes[i]);
}
Consumer<BytesIn> reader = in -> {
array[0] = (BytesMarshallable[]) encoder.decode(array[0], in);
try {
method.invoke(object, array[0]);
} catch (IllegalAccessException | InvocationTargetException e) {
Jvm.warn().on(getClass(), "Exception calling " + method + " " + Arrays.toString(array[0]), e);
}
};
long messageId = encoder.messageId();
if (messageId >= 0 && messageId < 1000) {
while (methodEncoders.size() <= messageId)
methodEncoders.add(null);
methodEncoders.set((int) messageId, reader);
} else {
methodEncoderMap.put(messageId, reader);
}
}
@Override
public MethodReaderInterceptorReturns methodReaderInterceptorReturns() {
throw new UnsupportedOperationException();
}
public boolean readOne() throws InvocationTargetRuntimeException {
throwExceptionIfClosed();
if (in.readRemaining() < 1)
return false;
long messageId = in.readStopBit();
Consumer<BytesIn> consumer;
if (messageId >= 0 && messageId < methodEncoders.size())
consumer = methodEncoders.get((int) messageId);
else
consumer = methodEncoderMap.get(messageId);
if (consumer == null) {
defaultParselet.accept(messageId, in);
} else {
consumer.accept(in);
}
return true;
}
@Override
public MethodReader closeIn(boolean closeIn) {
return this;
}
}

@ -1,72 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("rawtypes")
public class BytesMethodReaderBuilder implements MethodReaderBuilder {
private final BytesIn in;
private BytesParselet defaultParselet = createDefaultParselet();
private MethodEncoderLookup methodEncoderLookup = MethodEncoderLookup.BY_ANNOTATION;
public BytesMethodReaderBuilder(BytesIn in) {
this.in = in;
}
static BytesParselet createDefaultParselet() {
return (msg, in) -> {
Bytes bytes = (Bytes) in;
throw new IllegalArgumentException("Unknown message type " + msg + " " + bytes.toHexString());
};
}
@Override
public MethodReaderBuilder warnMissing(boolean warnMissing) {
// always true
return this;
}
public MethodEncoderLookup methodEncoderLookup() {
return methodEncoderLookup;
}
public BytesMethodReaderBuilder methodEncoderLookup(MethodEncoderLookup methodEncoderLookup) {
this.methodEncoderLookup = methodEncoderLookup;
return this;
}
public BytesParselet defaultParselet() {
return defaultParselet;
}
public BytesMethodReaderBuilder defaultParselet(BytesParselet defaultParselet) {
this.defaultParselet = defaultParselet;
return this;
}
@Override
public MethodReaderBuilder methodReaderInterceptorReturns(MethodReaderInterceptorReturns methodReaderInterceptorReturns) {
throw new UnsupportedOperationException();
}
public BytesMethodReader build(Object... objects) {
return new BytesMethodReader(in, defaultParselet, methodEncoderLookup, objects);
}
}

@ -1,27 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
import java.lang.reflect.InvocationHandler;
public interface BytesMethodWriterInvocationHandler extends InvocationHandler {
void onClose(Closeable closeable);
}

@ -1,96 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.Function;
@SuppressWarnings({"rawtypes", "unchecked"})
public interface BytesOut<Underlying> extends
ByteStringAppender<Bytes<Underlying>>,
BytesPrepender<Bytes<Underlying>>,
BytesComment<BytesOut<Underlying>> {
/**
* Proxy an interface so each message called is written to a file for replay.
*
* @param tClass primary interface
* @param additional any additional interfaces
* @return a proxy which implements the primary interface (additional interfaces have to be
* cast)
*/
default <T> T bytesMethodWriter( Class<T> tClass, Class... additional) {
Class[] interfaces = ObjectUtils.addAll(tClass, additional);
//noinspection unchecked
return (T) Proxy.newProxyInstance(tClass.getClassLoader(), interfaces,
new BinaryBytesMethodWriterInvocationHandler(MethodEncoderLookup.BY_ANNOTATION, this));
}
void writeMarshallableLength16(WriteBytesMarshallable marshallable);
/**
* Write a limit set of writeObject types.
*
* @param componentType expected.
* @param obj of componentType
*/
default void writeObject(Class componentType, Object obj) {
if (!componentType.isInstance(obj))
throw new IllegalArgumentException("Cannot serialize " + obj.getClass() + " as an " + componentType);
if (obj instanceof BytesMarshallable) {
((BytesMarshallable) obj).writeMarshallable(this);
return;
}
if (obj instanceof Enum) {
writeEnum((Enum) obj);
return;
}
if (obj instanceof BytesStore) {
BytesStore bs = (BytesStore) obj;
writeStopBit(bs.readRemaining());
write(bs);
return;
}
switch (componentType.getName()) {
case "java.lang.String":
writeUtf8((String) obj);
return;
case "java.lang.Double":
writeDouble((Double) obj);
return;
case "java.lang.Long":
writeLong((Long) obj);
return;
case "java.lang.Integer":
writeInt((Integer) obj);
return;
default:
throw new UnsupportedOperationException("Not supported " + componentType);
}
}
}

@ -1,24 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
@FunctionalInterface
public interface BytesParselet {
@SuppressWarnings("rawtypes")
void accept(long messageType, BytesIn in);
}

@ -1,109 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
public interface BytesPrepender<B extends BytesPrepender<B>> {
/**
* Clear a buffer, with a given padding to allow for prepending later. clearAndPad(0) is the same as clear()
*
* @param length to pad
* @return this
* @throws BufferOverflowException if the length &gt; capacity() - start()
*/
B clearAndPad(long length) throws BufferOverflowException;
/**
* Prepends a long in decimal, this method moves the readPosition() backwards.
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param value to prepend as text.
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
@SuppressWarnings("unchecked")
default B prepend(long value) throws BufferOverflowException {
BytesInternal.prepend(this, value);
return (B) this;
}
/**
* Write backward in binary a byte
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param bytes to prepend to.
*/
B prewrite(byte[] bytes) throws BufferOverflowException;
/**
* Write backward in binary a byte
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param bytes to prepend to.
*/
@SuppressWarnings("rawtypes")
B prewrite(BytesStore bytes) throws BufferOverflowException;
/**
* Write backward in binary a byte
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param b byte to prepend to.
*/
B prewriteByte(byte b) throws BufferOverflowException;
/**
* Write backward in binary a 2 byte int
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param i short to prepend to.
*/
B prewriteShort(short i) throws BufferOverflowException;
/**
* Write backward in binary a 4 byte int
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param i integer to prepend to.
*/
B prewriteInt(int i) throws BufferOverflowException;
/**
* Write backward in binary an 8 byte long
* <p>Note: it moves the readPosition not the writePosition / readLimit</p>
*
* @param l long to prepend to.
*/
B prewriteLong(long l) throws BufferOverflowException;
}

@ -1,115 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.io.Closeable;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.BufferOverflowException;
@SuppressWarnings({"rawtypes", "unchecked"})
public interface BytesRingBuffer extends BytesRingBufferStats, BytesConsumer, Closeable {
Logger LOG = LoggerFactory.getLogger(BytesRingBuffer.class);
static BytesRingBuffer newInstance( NativeBytesStore<Void> bytesStore) {
return newInstance(bytesStore, 1);
}
static MultiReaderBytesRingBuffer newInstance(
NativeBytesStore<Void> bytesStore,
int numReaders) {
try {
final Class<MultiReaderBytesRingBuffer> aClass = clazz();
final Constructor<MultiReaderBytesRingBuffer> constructor = aClass
.getDeclaredConstructor(BytesStore.class, int.class);
return constructor.newInstance(bytesStore, numReaders);
} catch (Exception e) {
LOG.error("This is a a commercial feature, please contact " +
"sales@chronicle.software to unlock this feature.");
throw Jvm.rethrow(e);
}
}
static Class<MultiReaderBytesRingBuffer> clazz() throws ClassNotFoundException {
//noinspection AccessStaticViaInstance
return (Class<MultiReaderBytesRingBuffer>) Class.forName(
"software.chronicle.enterprise.ring.EnterpriseRingBuffer");
}
static long sizeFor(long capacity) {
return sizeFor(capacity, 1);
}
static long sizeFor(long capacity, int numReaders) {
try {
//noinspection AccessStaticViaInstance
final Method sizeFor = Class.forName(
"software.chronicle.enterprise.queue.ChronicleRingBuffer").getMethod("sizeFor", long.class, int.class);
return (long) sizeFor.invoke(null, capacity, numReaders);
} catch (Exception e) {
LOG.error("This is a a commercial feature, please contact " +
"sales@chronicle.software to unlock this feature.");
throw Jvm.rethrow(e);
}
}
/**
* clears the ring buffer but moving the read position to the write position
*/
void clear();
/**
* Inserts the specified element at the tail of this queue if it is possible to do so
* immediately without exceeding the queue's capacity,
*
* @param bytes0 the {@code bytes0} that you wish to add to the ring buffer
* @return returning {@code true} upon success and {@code false} if this queue is full.
*/
boolean offer( BytesStore bytes0);
/**
* Retrieves and removes the head of this queue, or returns {@code null} if this queue is
* empty.
*
* @param using Bytes to read into.
* @return false if this queue is empty, or a populated buffer if the element was retried
* @throws BufferOverflowException is the {@code using} buffer is not large enough
*/
@Override
boolean read( BytesOut using);
long readRemaining();
boolean isEmpty();
BytesStore bytesStore();
}

@ -1,44 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.util.List;
public interface BytesRingBufferStats {
/**
* each time the ring is read, this logs the number of bytes in the write buffer, calling this
* method resets these statistics,
*
* @return Long.MAX_VALUE if no read calls were made since the last time this method was called.
*/
long minNumberOfWriteBytesRemaining();
/**
* @return the total capacity in bytes
*/
long capacity();
long getAndClearWriteCount();
long getAndClearMissedWriteCount();
long getAndClearContentionCount();
List<RingBufferReaderStats> readers();
}

@ -1,570 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.ReferenceCounted;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.crypto.Cipher;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import static java.lang.Math.min;
/**
* A immutable reference to some bytes with fixed extents. This can be shared safely across thread
* provided the data referenced is accessed in a thread safe manner. Only offset access within the
* capacity is possible.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface BytesStore<B extends BytesStore<B, Underlying>, Underlying>
extends RandomDataInput, RandomDataOutput<B>, ReferenceCounted, CharSequence {
/**
* This method builds a BytesStore using the bytes in a CharSequence. This chars are encoded
* using ISO_8859_1
*
* @param cs to convert
* @return BytesStore
*/
static BytesStore from( CharSequence cs) {
if (cs instanceof BytesStore)
return ((BytesStore) cs).copy();
return HeapBytesStore.wrap(cs.toString().getBytes(StandardCharsets.ISO_8859_1));
}
/**
* Wraps a byte[]. This means there is one copy in memory.
*
* @param bytes to wrap
* @return BytesStore
*/
static HeapBytesStore<byte[]> wrap( byte[] bytes) {
return HeapBytesStore.wrap(bytes);
}
/**
* Wraps a ByteBuffer which can be either on heap or off heap.
*
* @param bb to wrap
* @return BytesStore
*/
static BytesStore<?, ByteBuffer> wrap( ByteBuffer bb) {
return bb.isDirect()
? NativeBytesStore.wrap(bb)
: HeapBytesStore.wrap(bb);
}
/**
* @return a PointerBytesStore which can be set to any addressForRead
*/
static PointerBytesStore nativePointer() {
return new PointerBytesStore();
}
/**
* Return the addressForRead and length as a BytesStore
*
* @param address for the start
* @param length of data
* @return as a BytesStore
*/
static PointerBytesStore wrap(long address, long length) {
PointerBytesStore pbs = nativePointer();
pbs.set(address, length);
return pbs;
}
/**
* @return an empty, fixed sized Bytes
*/
static BytesStore empty() {
return NoBytesStore.noBytesStore();
}
/**
* @return whether it uses direct memory or not.
*/
@Override
boolean isDirectMemory();
/**
* @return a copy of this BytesStore.
*/
BytesStore<B, Underlying> copy();
/**
* @return a Bytes to wrap this ByteStore from the start() to the realCapacity().
* @throws IllegalStateException if this Bytes has been released.
*/
@Override
default Bytes<Underlying> bytesForRead() throws IllegalStateException {
try {
Bytes<Underlying> ret = bytesForWrite();
ret.readLimit(writeLimit());
ret.writeLimit(realCapacity());
ret.readPosition(start());
return ret;
} catch (BufferUnderflowException e) {
throw new IllegalStateException(e);
}
}
/**
* @return a Bytes for writing to this BytesStore
*/
@Override
default Bytes<Underlying> bytesForWrite() throws IllegalStateException {
return new VanillaBytes<>(this, writePosition(), writeLimit());
}
/**
* Returns if the {@code readPosition} is at the {@code start} and
* the {@code writeLimit} is at the {@code end}.
* <p>
* I.e {@code start() == readPosition() &amp;&amp; writeLimit() == capacity()}
*
* @return if the {@code readPosition} is at the {@code start} and
* the {@code writeLimit} is at the {@code end}
*/
default boolean isClear() {
return true;
}
/**
* @return the actual capacity available before resizing.
*/
@Override
default long realCapacity() {
return capacity();
}
/**
* @return The maximum limit you can set.
*/
@Override
long capacity();
/**
* @return the underlying object being wrapped, if there is one, or null if not.
*/
Underlying underlyingObject();
/**
* Use this test to determine if an offset is considered safe.
*/
default boolean inside(long offset) {
return start() <= offset && offset < safeLimit();
}
default boolean inside(long offset, long buffer) {
return start() <= offset && offset + buffer < safeLimit();
}
/**
* @return how many bytes can be safely read, i.e. what is the real capacity of the underlying data.
*/
default long safeLimit() {
return capacity();
}
/**
* Copy the data to another BytesStore as long as there is space available in the destination store.
*
* @param store to copy to
* @return how many bytes were copied
*/
default long copyTo( BytesStore store) {
long readPos = readPosition();
long writePos = store.writePosition();
long copy = min(readRemaining(), store.capacity());
long i = 0;
try {
for (; i < copy - 7; i += 8)
store.writeLong(writePos + i, readLong(readPos + i));
for (; i < copy; i++)
store.writeByte(writePos + i, readByte(readPos + i));
} catch (BufferOverflowException | BufferUnderflowException e) {
throw new AssertionError(e);
}
return copy;
}
default void copyTo( OutputStream out) throws IOException {
BytesInternal.copy(this, out);
}
/**
* Fill the BytesStore with zeros
*
* @param start first byte inclusive
* @param end last byte exclusive.
* @return this.
*/
@Override
default B zeroOut(long start, long end) {
if (end <= start)
return (B) this;
if (start < start())
start = start();
if (end > capacity())
end = capacity();
long i = start;
try {
for (; i < end - 7; i += 8L)
writeLong(i, 0L);
for (; i < end; i++)
writeByte(i, 0);
} catch (BufferOverflowException | IllegalArgumentException e) {
throw new AssertionError(e);
}
return (B) this;
}
/**
* This method is inherited from CharSequence so result should be the length of the contained
* chars sequence although it actually returns the number of underlying bytes. These 2 numbers are only the same
* if the encoding we are using is single char for single byte.
*
* @return length in bytes to read or Integer.MAX_VALUE if longer.
*/
@Override
default int length() {
return (int) Math.min(Integer.MAX_VALUE, readRemaining());
}
/**
* Assume ISO-8859-1 encoding, subclasses can override this.
*/
@Override
default char charAt(int index) throws IndexOutOfBoundsException {
try {
return (char) readUnsignedByte(readPosition() + index);
} catch (BufferUnderflowException e) {
throw new IndexOutOfBoundsException((readPosition() + index) + " >= " + readLimit());
}
}
/**
* Not supported.
*/
@Override
default CharSequence subSequence(int start, int end) {
throw new UnsupportedOperationException("todo");
}
/**
* By default the maximum length of data shown is 256 characters. Use toDebugString(long) if you want more.
*
* @return This BytesStore as a DebugString.
*/
default String toDebugString() {
return toDebugString(512);
}
/**
* @param maxLength the maximum len of the output
* @return This BytesStore as a DebugString.
*/
default String toDebugString(long maxLength) {
return BytesInternal.toDebugString(this, maxLength);
}
/**
* @return the underlying BytesStore
*/
default BytesStore bytesStore() {
return this;
}
/**
* Check if a portion of a BytesStore matches this one.
*
* @param bytesStore to match against
* @param length to match.
* @return true if the bytes up to min(length, this.length(), bytesStore.length()) matched.
*/
default boolean equalBytes( BytesStore bytesStore, long length)
throws BufferUnderflowException {
return length == 8 && bytesStore.length() >= 8
? readLong(readPosition()) == bytesStore.readLong(bytesStore.readPosition())
: BytesInternal.equalBytesAny(this, bytesStore, length);
}
/**
* Return the bytes sum of the readable bytes.
*
* @return unsigned byte sum.
*/
default int byteCheckSum() throws IORuntimeException {
return byteCheckSum(readPosition(), readLimit());
}
default int byteCheckSum(long start, long end) {
int sum = 0;
for (long i = start; i < end; i++) {
sum += readByte(i);
}
return sum & 0xFF;
}
/**
* Does the BytesStore end with a character?
*
* @param c to look for
* @return true if its the last character.
*/
default boolean endsWith(char c) {
try {
return readRemaining() > 0 && readUnsignedByte(readLimit() - 1) == c;
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
/**
* Does the BytesStore start with a character?
*
* @param c to look for
* @return true if its the last character.
*/
default boolean startsWith(char c) {
try {
return readRemaining() > 0 && readUnsignedByte(readPosition()) == c;
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
/**
* Compare the contents of the BytesStores.
*
* @param bytesStore to compare with
* @return true if they contain the same data.
*/
default boolean contentEquals( BytesStore bytesStore) {
return BytesInternal.contentEqual(this, bytesStore);
}
default boolean startsWith( BytesStore bytesStore) {
return BytesInternal.startsWith(this, bytesStore);
}
default String to8bitString() throws IllegalArgumentException {
return BytesInternal.to8bitString(this);
}
/**
* Perform a <i>not</i> atomic add and get operation for an unsigned byte value. This method
* <i>does not</i> check for unsigned byte overflow.
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
*/
default int addAndGetUnsignedByteNotAtomic(long offset, int adding) throws BufferUnderflowException {
try {
int r = (readUnsignedByte(offset) + adding) & 0xFF;
writeByte(offset, (byte) r);
return r;
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
/**
* Perform a <i>not</i> atomic add and get operation for a short value.
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
*/
default short addAndGetShortNotAtomic(long offset, short adding) throws BufferUnderflowException {
try {
short r = (short) (readShort(offset) + adding);
writeByte(offset, r);
return r;
} catch (BufferOverflowException | IllegalArgumentException e) {
throw new AssertionError(e);
}
}
/**
* Perform a <i>not</i> atomic add and get operation for an int value.
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
*/
default int addAndGetIntNotAtomic(long offset, int adding) throws BufferUnderflowException {
try {
int r = readInt(offset) + adding;
writeInt(offset, r);
return r;
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
/**
* Perform a <i>not</i> atomic add and get operation for a float value.
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
*/
default double addAndGetDoubleNotAtomic(long offset, double adding) throws BufferUnderflowException {
try {
double r = readDouble(offset) + adding;
writeDouble(offset, r);
return r;
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
/**
* Perform a <i>not</i> atomic add and get operation for a float value.
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
*/
default float addAndGetFloatNotAtomic(long offset, float adding) throws BufferUnderflowException {
try {
float r = readFloat(offset) + adding;
writeFloat(offset, r);
return r;
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
void move(long from, long to, long length) throws BufferUnderflowException;
/**
* Write a value which is not smaller.
*
* @param offset to write to
* @param atLeast value it is at least.
*/
default void writeMaxLong(long offset, long atLeast) throws BufferUnderflowException {
try {
for (; ; ) {
long v = readVolatileLong(offset);
if (v >= atLeast)
return;
if (compareAndSwapLong(offset, v, atLeast))
return;
}
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
/**
* Write a value which is not smaller.
*
* @param offset to write to
* @param atLeast value it is at least.
*/
default void writeMaxInt(long offset, int atLeast) throws BufferUnderflowException {
try {
for (; ; ) {
int v = readVolatileInt(offset);
if (v >= atLeast)
return;
if (compareAndSwapInt(offset, v, atLeast))
return;
}
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
default boolean isEmpty() {
return readRemaining() == 0;
}
default void cipher( Cipher cipher, Bytes outBytes, ByteBuffer using1, ByteBuffer using2) throws IllegalStateException {
long readPos = outBytes.readPosition();
try {
long writePos = outBytes.writePosition();
BytesStore inBytes;
long size = readRemaining();
if (this.isDirectMemory()) {
inBytes = this;
} else {
inBytes = NativeBytesStore.nativeStore(size);
this.copyTo(inBytes);
}
BytesInternal.assignBytesStoreToByteBuffer(inBytes, using1);
int outputSize = cipher.getOutputSize(Math.toIntExact(size));
outBytes.ensureCapacity(writePos + outputSize);
outBytes.readPositionRemaining(writePos, outputSize);
BytesInternal.assignBytesStoreToByteBuffer(outBytes, using2);
int len = cipher.update(using1, using2);
len += cipher.doFinal(using1, using2);
assert len == using2.position();
outBytes.writePosition(writePos + using2.position());
} catch ( Exception e) {
throw new IllegalStateException(e);
} finally {
try {
outBytes.readPosition(readPos);
} catch (BufferUnderflowException e) {
//noinspection ThrowFromFinallyBlock
throw new IllegalStateException(e);
}
}
}
default void cipher( Cipher cipher, Bytes outBytes) throws IllegalStateException {
cipher(cipher, outBytes, BytesInternal.BYTE_BUFFER_TL.get(), BytesInternal.BYTE_BUFFER2_TL.get());
}
/**
* @return whether this BytesStore is writable.
*/
default boolean readWrite() {
return true;
}
}

@ -1,115 +0,0 @@
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.function.Function;
@SuppressWarnings("rawtypes")
public class BytesTextMethodTester<T> {
private final String input;
private final Class<T> outputClass;
private final String output;
private final Function<T, Object> componentFunction;
private String setup;
private Function<String, String> afterRun;
private String expected;
private String actual;
public BytesTextMethodTester(String input, Function<T, Object> componentFunction, Class<T> outputClass, String output) {
this.input = input;
this.outputClass = outputClass;
this.output = output;
this.componentFunction = componentFunction;
}
public String setup() {
return setup;
}
public BytesTextMethodTester setup(String setup) {
this.setup = setup;
return this;
}
public Function<String, String> afterRun() {
return afterRun;
}
public BytesTextMethodTester afterRun(Function<String, String> afterRun) {
this.afterRun = afterRun;
return this;
}
public BytesTextMethodTester run() throws IOException {
Bytes<?> bytes2 = new HexDumpBytes();
T writer = bytes2.bytesMethodWriter(outputClass);
Object component = componentFunction.apply(writer);
Object[] components = component instanceof Object[]
? (Object[]) component
: new Object[]{component};
if (setup != null) {
Bytes bytes0 = HexDumpBytes.fromText(BytesUtil.readFile(setup));
BytesMethodReader reader0 = bytes0.bytesMethodReaderBuilder()
.defaultParselet(this::unknownMessageId)
.build(components);
while (reader0.readOne()) {
bytes2.clear();
}
bytes2.clear();
}
// expected
expected = BytesUtil.readFile(output).toString().trim().replace("\r", "");
Bytes text = BytesUtil.readFile(input);
for (String text2 : text.toString().split("###[^\n]*\n")) {
if (text2.trim().length() <= 0)
continue;
Bytes bytes = HexDumpBytes.fromText(text2);
BytesMethodReader reader = bytes.bytesMethodReaderBuilder()
.defaultParselet(this::unknownMessageId)
.build(components);
while (reader.readOne()) {
if (bytes.readRemaining() > 1)
bytes2.comment("## End Of Message");
}
bytes.releaseLast();
bytes2.comment("## End Of Block");
}
bytes2.comment("## End Of Test");
actual = bytes2.toHexString().trim();
if (afterRun != null) {
expected = afterRun.apply(expected);
actual = afterRun.apply(actual);
}
bytes2.releaseLast();
return this;
}
private void unknownMessageId(long id, BytesIn b) {
Jvm.warn().on(getClass(), "Unknown message id " + Long.toHexString(id));
b.readPosition(b.readLimit());
}
public String expected() {
return expected;
}
public String actual() {
return actual;
}
}

@ -1,331 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.ClassLocal;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.UnsafeMemory;
import net.openhft.chronicle.core.io.AbstractReferenceCounted;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.IOTools;
import net.openhft.chronicle.core.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.misc.Unsafe;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static net.openhft.chronicle.core.io.IOTools.*;
@SuppressWarnings("rawtypes")
public enum BytesUtil {
;
private static final int[] NO_INTS = {};
private static final ClassLocal<int[]> TRIVIALLY_COPYABLE = ClassLocal.withInitial(BytesUtil::isTriviallyCopyable0);
/**
* Is the whole class trivially copyable
*
* @param clazz to check
* @return true if the whole class is trivially copyable
*/
public static boolean isTriviallyCopyable(Class clazz) {
return TRIVIALLY_COPYABLE.get(clazz).length > 0;
}
static int[] isTriviallyCopyable0(Class clazz) {
if (clazz.isArray()) {
Class componentType = clazz.getComponentType();
if (componentType.isPrimitive())
return new int[]{UnsafeMemory.UNSAFE.arrayBaseOffset(clazz)};
return NO_INTS;
}
List<Field> fields = new ArrayList<>();
while (clazz != null && clazz != Object.class) {
Collections.addAll(fields, clazz.getDeclaredFields());
clazz = clazz.getSuperclass();
}
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (Field field : fields) {
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers))
continue;
long offset2 = UnsafeMemory.UNSAFE.objectFieldOffset(field);
int size = sizeOf(field.getType());
min = (int) Math.min(min, offset2);
max = (int) Math.max(max, offset2 + size);
if (Modifier.isTransient(modifiers))
return NO_INTS;
if (!field.getType().isPrimitive())
return NO_INTS;
}
return new int[]{min, max};
}
/**
* Are all the fields in the range given trivially copyable
*
* @param clazz to check
* @return true if the fields in range are trivially copyable.
*/
public static boolean isTriviallyCopyable(Class clazz, int offset, int length) {
int[] ints = TRIVIALLY_COPYABLE.get(clazz);
if (ints.length == 0)
return false;
return offset >= ints[0] && (ints.length == 1 || offset + length <= ints[1]);
}
public static int[] triviallyCopyableRange(Class clazz) {
return TRIVIALLY_COPYABLE.get(clazz);
}
private static int sizeOf(Class<?> type) {
return type == boolean.class || type == byte.class ? 1
: type == short.class || type == char.class ? 2
: type == int.class || type == float.class ? 4
: type == long.class || type == double.class ? 8
: Unsafe.ARRAY_OBJECT_INDEX_SCALE;
}
public static String findFile( String name) throws FileNotFoundException {
File file = new File(name);
URL url = null;
if (!file.exists()) {
url = urlFor(name);
String file2 = url.getFile()
.replace("target/test-classes", "src/test/resources");
file = new File(file2);
}
if (!file.exists())
throw new FileNotFoundException(name);
return file.getAbsolutePath();
}
public static Bytes readFile( String name) throws IOException {
if (name.startsWith("=")) {
return Bytes.from(name.substring(1));
}
File file = new File(name);
URL url = null;
if (!file.exists()) {
url = urlFor(name);
file = new File(url.getFile());
}
return // name.endsWith(".gz") || !file.exists() || OS.isWindows() ?
Bytes.wrapForRead(readAsBytes(url == null ? new FileInputStream(file) : open(url)));
//: MappedFile.readOnly(file).acquireBytesForRead(0);
}
public static void writeFile(String file, Bytes<byte[]> bytes) throws IOException {
try (OutputStream os = new FileOutputStream(file)) {
os.write(bytes.underlyingObject());
}
}
public static boolean bytesEqual(
RandomDataInput a, long offset,
RandomDataInput second, long secondOffset, long len)
throws BufferUnderflowException {
long i = 0;
while (len - i >= 8L) {
if (a.readLong(offset + i) != second.readLong(secondOffset + i))
return false;
i += 8L;
}
if (len - i >= 4L) {
if (a.readInt(offset + i) != second.readInt(secondOffset + i))
return false;
i += 4L;
}
if (len - i >= 2L) {
if (a.readShort(offset + i) != second.readShort(secondOffset + i))
return false;
i += 2L;
}
if (i < len)
return a.readByte(offset + i) == second.readByte(secondOffset + i);
return true;
}
public static boolean bytesEqual( CharSequence cs, RandomDataInput bs, long offset, int length) {
if (cs == null || cs.length() != length)
return false;
for (int i = 0; i < length; i++) {
if (cs.charAt(i) != bs.readUnsignedByte(offset + i))
return false;
}
return true;
}
public static boolean equals(Object o1, Object o2) {
if (o1 == o2) return true;
if (o1 instanceof CharSequence && o2 instanceof CharSequence)
return StringUtils.isEqual((CharSequence) o1, (CharSequence) o2);
return o1 != null && o1.equals(o2);
}
public static int asInt( String str) {
ByteBuffer bb = ByteBuffer.wrap(str.getBytes(StandardCharsets.ISO_8859_1)).order(ByteOrder.nativeOrder());
return bb.getInt();
}
public static int stopBitLength(long n) {
if ((n & ~0x7F) == 0) {
return 1;
}
if ((n & ~0x3FFF) == 0) {
return 2;
}
return BytesInternal.stopBitLength0(n);
}
public static char[] toCharArray( Bytes bytes) {
final char[] chars = new char[Maths.toUInt31(bytes.readRemaining())];
for (int i = 0; i < bytes.readRemaining(); i++) {
chars[i] = (char) bytes.readUnsignedByte(i + bytes.readPosition());
}
return chars;
}
public static char[] toCharArray( Bytes bytes, long position, int length) {
final char[] chars = new char[length];
int j = 0;
for (int i = 0; i < length; i++) {
chars[j++] = (char) bytes.readUnsignedByte(position + i);
}
return chars;
}
public static long readStopBit( StreamingDataInput in) throws IORuntimeException {
return BytesInternal.readStopBit(in);
}
public static void writeStopBit( StreamingDataOutput out, long n) {
BytesInternal.writeStopBit(out, n);
}
public static void parseUtf8(
StreamingDataInput in, Appendable appendable, int utflen)
throws UTFDataFormatRuntimeException {
BytesInternal.parseUtf8(in, appendable, true, utflen);
}
public static void appendUtf8( StreamingDataOutput out, CharSequence cs) {
BytesInternal.appendUtf8(out, cs, 0, cs.length());
}
// used by Chronicle FIX.
public static void appendBytesFromStart( Bytes bytes, long startPosition, StringBuilder sb) {
try {
BytesInternal.parse8bit(startPosition, bytes, sb, (int) (bytes.readPosition() - startPosition));
sb.append('\u2016');
sb.append(bytes);
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
public static void readMarshallable( ReadBytesMarshallable marshallable, BytesIn bytes) {
BytesMarshaller.BYTES_MARSHALLER_CL.get(marshallable.getClass())
.readMarshallable(marshallable, bytes);
}
public static void writeMarshallable( WriteBytesMarshallable marshallable, BytesOut bytes) {
BytesMarshaller.BYTES_MARSHALLER_CL.get(marshallable.getClass())
.writeMarshallable(marshallable, bytes);
}
@Deprecated(/* to be removed in x.22 */)
public static long utf8Length( CharSequence toWrite) {
return AppendableUtil.findUtf8Length(toWrite);
}
static String asString(String s, Throwable t) {
StringWriter sw = new StringWriter();
sw.append(s).append("\n");
t.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
// calls the BackgroundResourceReleaser and AbstractCloseable.assertCloseableClose first.
public static void checkRegisteredBytes() {
AbstractReferenceCounted.assertReferencesReleased();
}
public static boolean byteToBoolean(byte b) {
return b != 0 && b != 'N' && b != 'n';
}
public static long roundUpTo64ByteAlign(long x) {
return (x + 63L) & ~63L;
}
public static long roundUpTo8ByteAlign(long x) {
return (x + 7L) & ~7L;
}
public static void read8ByteAlignPadding(Bytes<?> bytes) {
bytes.readPosition(roundUpTo8ByteAlign(bytes.readPosition()));
}
public static void write8ByteAlignPadding(Bytes<?> bytes) {
long start = bytes.writePosition();
long end = roundUpTo8ByteAlign(start);
bytes.writePosition(end);
bytes.zeroOut(start, end);
}
public static String toDebugString( RandomDataInput bytes, long start, long maxLength) {
BytesStore bytes2 = bytes.subBytes(start, maxLength);
return bytes2.toDebugString(maxLength);
}
@Deprecated(/* to be removed in x.22 */)
public static boolean unregister(BytesStore bs) {
IOTools.unmonitor(bs);
return true;
}
static class WarnUncheckedElasticBytes {
static {
Jvm.debug().on(WarnUncheckedElasticBytes.class, "Wrapping elastic bytes with unchecked() will require calling ensureCapacity() as needed!");
}
static void warn() {
// static block does the work.
}
}
}

@ -1,30 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.annotation.DontChain;
@DontChain
public interface CommonMarshallable {
/**
* @return whether this message should be written as self describing
*/
default boolean usesSelfDescribingMessage() {
return false;
}
}

@ -1,39 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.IORuntimeException;
/**
* thrown when the TcpChannelHub drops its connection to the server
*/
// TODO Move to network where it is used.
public class ConnectionDroppedException extends IORuntimeException {
public ConnectionDroppedException(String message) {
super(message);
}
public ConnectionDroppedException(Throwable e) {
super(e);
}
public ConnectionDroppedException(String s, Throwable e) {
super(s, e);
}
}

@ -1,25 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
/**
* Marker interface for implementors of {@link Byteable} that indicates
* that size requirements can only be calculated on a user-supplied instance.
*/
public interface DynamicallySized {
}

@ -1,179 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import static net.openhft.chronicle.bytes.BinaryWireCode.*;
public class GuardedNativeBytes<Underlying> extends NativeBytes<Underlying> {
static final byte BYTE_T = (byte) INT8;
static final byte SHORT_T = (byte) INT16;
static final byte INT_T = (byte) INT32;
static final byte LONG_T = (byte) INT64;
static final byte STOP_T = (byte) STOP_BIT;
static final byte FLOAT_T = (byte) FLOAT32;
static final byte DOUBLE_T = (byte) FLOAT64;
private static final String[] STRING_FOR_CODE = _stringForCode(GuardedNativeBytes.class);
public GuardedNativeBytes( BytesStore store, long capacity) throws IllegalStateException {
super(store, capacity);
}
@Override
public Bytes<Underlying> writeByte(byte i8) throws BufferOverflowException {
super.writeByte(BYTE_T);
return super.writeByte(i8);
}
@Override
public Bytes<Underlying> rawWriteByte(byte i8) throws BufferOverflowException {
return super.writeByte(i8);
}
@Override
public Bytes<Underlying> rawWriteInt(int i) throws BufferOverflowException {
return super.writeInt(i);
}
@Override
public byte readByte() {
expectByte(BYTE_T);
return super.readByte();
}
@Override
public byte rawReadByte() {
return super.readByte();
}
@Override
public int rawReadInt() {
return super.readInt();
}
@Override
public int readUnsignedByte() {
expectByte(BYTE_T);
return super.readUnsignedByte();
}
@Override
public Bytes<Underlying> writeShort(short i16) throws BufferOverflowException {
super.writeByte(SHORT_T);
return super.writeShort(i16);
}
@Override
public short readShort() throws BufferUnderflowException {
expectByte(SHORT_T);
return super.readShort();
}
@Override
public Bytes<Underlying> writeStopBit(char x) throws BufferOverflowException {
super.writeByte(STOP_T);
return super.writeStopBit(x);
}
@Override
public Bytes<Underlying> writeStopBit(long x) throws BufferOverflowException {
super.writeByte(STOP_T);
return super.writeStopBit(x);
}
@Override
public long readStopBit() throws IORuntimeException {
expectByte(STOP_T);
return super.readStopBit();
}
@Override
public char readStopBitChar() throws IORuntimeException {
expectByte(STOP_T);
return super.readStopBitChar();
}
@Override
public Bytes<Underlying> writeInt(int i) throws BufferOverflowException {
super.writeByte(INT_T);
return super.writeInt(i);
}
@Override
public int readInt() throws BufferUnderflowException {
expectByte(INT_T);
return super.readInt();
}
@Override
public Bytes writeLong(long i64) throws BufferOverflowException {
super.writeByte(LONG_T);
return super.writeLong(i64);
}
@Override
public long readLong() throws BufferUnderflowException {
expectByte(LONG_T);
return super.readLong();
}
@Override
public Bytes<Underlying> writeFloat(float f) throws BufferOverflowException {
super.writeByte(FLOAT_T);
return super.writeFloat(f);
}
@Override
public float readFloat() throws BufferUnderflowException {
expectByte(FLOAT_T);
return super.readFloat();
}
@Override
public Bytes<Underlying> writeDouble(double d) throws BufferOverflowException {
super.writeByte(DOUBLE_T);
return super.writeDouble(d);
}
@Override
public double readDouble() throws BufferUnderflowException {
expectByte(DOUBLE_T);
return super.readDouble();
}
private void expectByte(byte expected) {
byte type = super.readByte();
if (type != expected)
throw new IllegalStateException("Expected " + STRING_FOR_CODE[expected & 0xFF]
+ " but was " + STRING_FOR_CODE[type & 0xFF]);
}
}

@ -1,402 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.util.DecoratedBufferOverflowException;
import net.openhft.chronicle.bytes.util.DecoratedBufferUnderflowException;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.Memory;
import net.openhft.chronicle.core.OS;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.function.Function;
/**
* Wrapper for Heap ByteBuffers and arrays.
*/
@SuppressWarnings("restriction")
public class HeapBytesStore<Underlying>
extends AbstractBytesStore<HeapBytesStore<Underlying>, Underlying> {
private static final Memory MEMORY = OS.memory();
private final Object realUnderlyingObject;
private final int dataOffset;
private final long capacity;
private final Underlying underlyingObject;
private HeapBytesStore( ByteBuffer byteBuffer) {
super(false);
//noinspection unchecked
this.underlyingObject = (Underlying) byteBuffer;
this.realUnderlyingObject = byteBuffer.array();
this.dataOffset = Jvm.arrayByteBaseOffset() + byteBuffer.arrayOffset();
this.capacity = byteBuffer.capacity();
}
private HeapBytesStore( byte [] byteArray) {
super(false);
//noinspection unchecked
this.underlyingObject = (Underlying) byteArray;
this.realUnderlyingObject = byteArray;
this.dataOffset = Jvm.arrayByteBaseOffset();
this.capacity = byteArray.length;
}
// Used by Chronicle-Map.
public static HeapBytesStore<byte[]> wrap( byte[] byteArray) {
return new HeapBytesStore<>(byteArray);
}
// Used by Chronicle-Map.
public static HeapBytesStore<ByteBuffer> wrap( ByteBuffer bb) {
return new HeapBytesStore<>(bb);
}
@Override
public boolean isDirectMemory() {
return false;
}
@Override
public void move(long from, long to, long length) {
if (from < 0 || to < 0) throw new BufferUnderflowException();
//noinspection SuspiciousSystemArraycopy
System.arraycopy(realUnderlyingObject, Maths.toUInt31(from), realUnderlyingObject, Maths.toUInt31(to), Maths.toUInt31(length));
}
@Override
public String toString() {
try {
return BytesInternal.toString(this);
} catch (IllegalStateException e) {
return e.toString();
}
}
@Override
public BytesStore<HeapBytesStore<Underlying>, Underlying> copy() {
throw new UnsupportedOperationException("todo");
}
@Override
protected void performRelease() {
// nothing to do
}
@Override
public long capacity() {
return capacity;
}
@Override
public Underlying underlyingObject() {
return underlyingObject;
}
@Override
public boolean compareAndSwapInt(long offset, int expected, int value) {
return MEMORY.compareAndSwapInt(realUnderlyingObject, dataOffset + offset, expected, value);
}
@Override
public void testAndSetInt(long offset, int expected, int value) {
MEMORY.testAndSetInt(realUnderlyingObject, dataOffset + offset, expected, value);
}
@Override
public boolean compareAndSwapLong(long offset, long expected, long value) {
return MEMORY.compareAndSwapLong(
realUnderlyingObject, dataOffset + offset, expected, value);
}
@Override
public byte readByte(long offset) throws BufferUnderflowException {
checkOffset(offset, 1);
return MEMORY.readByte(realUnderlyingObject, dataOffset + offset);
}
@Override
public short readShort(long offset) throws BufferUnderflowException {
checkOffset(offset, 2);
return MEMORY.readShort(realUnderlyingObject, dataOffset + offset);
}
@Override
public int readInt(long offset) throws BufferUnderflowException {
checkOffset(offset, 4);
return MEMORY.readInt(realUnderlyingObject, dataOffset + offset);
}
@Override
public long readLong(long offset) throws BufferUnderflowException {
checkOffset(offset, 8);
return MEMORY.readLong(realUnderlyingObject, dataOffset + offset);
}
@Override
public float readFloat(long offset) throws BufferUnderflowException {
checkOffset(offset, 4);
return MEMORY.readFloat(realUnderlyingObject, dataOffset + offset);
}
@Override
public double readDouble(long offset) throws BufferUnderflowException {
checkOffset(offset, 8);
return MEMORY.readDouble(realUnderlyingObject, dataOffset + offset);
}
@Override
public byte readVolatileByte(long offset) throws BufferUnderflowException {
checkOffset(offset, 1);
return MEMORY.readVolatileByte(realUnderlyingObject, dataOffset + offset);
}
@Override
public short readVolatileShort(long offset) throws BufferUnderflowException {
checkOffset(offset, 2);
return MEMORY.readVolatileShort(realUnderlyingObject, dataOffset + offset);
}
@Override
public int readVolatileInt(long offset) throws BufferUnderflowException {
checkOffset(offset, 4);
return MEMORY.readVolatileInt(realUnderlyingObject, dataOffset + offset);
}
@Override
public long readVolatileLong(long offset) throws BufferUnderflowException {
checkOffset(offset, 8);
return MEMORY.readVolatileLong(realUnderlyingObject, dataOffset + offset);
}
@Override
public HeapBytesStore<Underlying> writeByte(long offset, byte b)
throws BufferOverflowException {
writeCheckOffset(offset, 1);
MEMORY.writeByte(realUnderlyingObject, dataOffset + offset, b);
return this;
}
@Override
public HeapBytesStore<Underlying> writeShort(long offset, short i16)
throws BufferOverflowException {
writeCheckOffset(offset, 2);
MEMORY.writeShort(realUnderlyingObject, dataOffset + offset, i16);
return this;
}
@Override
public HeapBytesStore<Underlying> writeInt(long offset, int i32)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
MEMORY.writeInt(realUnderlyingObject, dataOffset + offset, i32);
return this;
}
@Override
public HeapBytesStore<Underlying> writeOrderedInt(long offset, int i32)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
MEMORY.writeOrderedInt(realUnderlyingObject, dataOffset + offset, i32);
return this;
}
@Override
public HeapBytesStore<Underlying> writeLong(long offset, long i64)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
MEMORY.writeLong(realUnderlyingObject, dataOffset + offset, i64);
return this;
}
@Override
public HeapBytesStore<Underlying> writeOrderedLong(long offset, long i)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
MEMORY.writeOrderedLong(realUnderlyingObject, dataOffset + offset, i);
return this;
}
@Override
public HeapBytesStore<Underlying> writeFloat(long offset, float f)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
MEMORY.writeFloat(realUnderlyingObject, dataOffset + offset, f);
return this;
}
@Override
public HeapBytesStore<Underlying> writeDouble(long offset, double d)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
MEMORY.writeDouble(realUnderlyingObject, dataOffset + offset, d);
return this;
}
@Override
public HeapBytesStore<Underlying> writeVolatileByte(long offset, byte i8)
throws BufferOverflowException {
writeCheckOffset(offset, 1);
MEMORY.writeVolatileByte(realUnderlyingObject, dataOffset + offset, i8);
return this;
}
@Override
public HeapBytesStore<Underlying> writeVolatileShort(long offset, short i16)
throws BufferOverflowException {
writeCheckOffset(offset, 2);
MEMORY.writeVolatileShort(realUnderlyingObject, dataOffset + offset, i16);
return this;
}
@Override
public HeapBytesStore<Underlying> writeVolatileInt(long offset, int i32)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
MEMORY.writeVolatileInt(realUnderlyingObject, dataOffset + offset, i32);
return this;
}
@Override
public HeapBytesStore<Underlying> writeVolatileLong(long offset, long i64)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
MEMORY.writeVolatileLong(realUnderlyingObject, dataOffset + offset, i64);
return this;
}
@Override
public HeapBytesStore<Underlying> write(
long offsetInRDO, byte[] bytes, int offset, int length) throws BufferOverflowException {
writeCheckOffset(offsetInRDO, length);
MEMORY.copyMemory(
bytes, offset, realUnderlyingObject, this.dataOffset + offsetInRDO, length);
return this;
}
@Override
public void write(
long offsetInRDO, ByteBuffer bytes, int offset, int length) throws BufferOverflowException {
writeCheckOffset(offsetInRDO, length);
assert realUnderlyingObject == null || dataOffset >= (Jvm.is64bit() ? 12 : 8);
if (bytes.isDirect()) {
MEMORY.copyMemory(Jvm.address(bytes), realUnderlyingObject,
this.dataOffset + offsetInRDO, length);
} else {
MEMORY.copyMemory(bytes.array(), offset, realUnderlyingObject,
this.dataOffset + offsetInRDO, length);
}
}
@Override
public HeapBytesStore<Underlying> write(long writeOffset,
RandomDataInput bytes, long readOffset, long length) {
long i;
for (i = 0; i < length - 7; i += 8) {
long x = bytes.readLong(readOffset + i);
writeLong(writeOffset + i, x);
}
for (; i < length; i++) {
byte x = bytes.readByte(readOffset + i);
writeByte(writeOffset + i, x);
}
return this;
}
@Override
public long addressForRead(long offset) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public long addressForWrite(long offset) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public long addressForWritePosition() throws UnsupportedOperationException, BufferOverflowException {
throw new UnsupportedOperationException();
}
@Override
public void nativeRead(long position, long address, long size) {
throw new UnsupportedOperationException("todo");
}
@Override
public void nativeWrite(long address, long position, long size) {
throw new UnsupportedOperationException("todo");
}
@SuppressWarnings("rawtypes")
@Override
public boolean equals(Object obj) {
return obj instanceof BytesStore && BytesInternal.contentEqual(this, (BytesStore) obj);
}
@Override
public boolean sharedMemory() {
return false;
}
private void checkOffset(long offset, int size) throws BufferUnderflowException {
checkBounds(offset, size, DecoratedBufferUnderflowException::new);
}
private void writeCheckOffset(long offset, int size) throws BufferOverflowException {
checkBounds(offset, size, DecoratedBufferOverflowException::new);
}
private void checkBounds(final long offset, final int size,
final Function<String, RuntimeException> exceptionFunction) {
if (offset < start() || offset + size > capacity) {
throw exceptionFunction.apply(
String.format("Offset: %d, start: %d, size: %d, capacity: %d",
offset, start(), size, capacity));
}
}
}

@ -1,9 +0,0 @@
package net.openhft.chronicle.bytes;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@FunctionalInterface
public interface Invocation {
Object invoke(Method m, Object o, Object[] args) throws InvocationTargetException;
}

@ -1,115 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.ReferenceOwner;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferUnderflowException;
/**
* BytesStore to wrap memory mapped data.
*/
public class MappedBytesStore extends NativeBytesStore<Void> {
private final MappedFile mappedFile;
private final long start;
private final long safeLimit;
protected MappedBytesStore(ReferenceOwner owner, MappedFile mappedFile, long start, long address, long capacity, long safeCapacity) throws IllegalStateException {
super(address, start + capacity, new OS.Unmapper(address, capacity), false);
this.mappedFile = mappedFile;
this.start = start;
this.safeLimit = start + safeCapacity;
reserveTransfer(INIT, owner);
}
/**
* Fetch the capacity of the underlying file
* This can differ from the exposed capacity() of this bytes store (which has been page aligned)
*
* @return - capacity of the underlying file
*/
public long underlyingCapacity() {
return mappedFile.capacity();
}
@Override
public Bytes<Void> bytesForRead() throws IllegalStateException {
try {
return new VanillaBytes<Void>(this)
.readLimit(writeLimit())
.readPosition(start());
} catch (BufferUnderflowException e) {
throw new IllegalStateException(e);
}
}
@Override
public VanillaBytes<Void> bytesForWrite() throws IllegalStateException {
return new VanillaBytes<>(this);
}
@Override
public boolean inside(long offset) {
return start <= offset && offset < safeLimit;
}
@Override
public boolean inside(long offset, long buffer) {
// this is correct that it uses the maximumLimit, yes it is different than the method above.
return start <= offset && offset + buffer < limit;
}
@Override
public long safeLimit() {
return safeLimit;
}
@Override
public byte readByte(long offset) {
return memory.readByte(address - start + offset);
}
@Override
public NativeBytesStore<Void> writeOrderedInt(long offset, int i) {
memory.writeOrderedInt(address - start + offset, i);
return this;
}
@Override
protected long translate(long offset) {
assert offset >= start;
assert offset < limit;
return offset - start;
}
@Override
public long start() {
return start;
}
@Override
public long readPosition() {
return start();
}
}

@ -1,28 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.ReferenceOwner;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface MappedBytesStoreFactory {
MappedBytesStore create(ReferenceOwner owner, MappedFile mappedFile, long start, long address, long capacity, long safeCapacity);
}

@ -1,541 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.CleaningRandomAccessFile;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.AbstractCloseableReferenceCounted;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.ReferenceOwner;
import net.openhft.chronicle.core.onoes.Slf4jExceptionHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.channels.FileLock;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import static net.openhft.chronicle.core.io.Closeable.closeQuietly;
/**
* A memory mapped files which can be randomly accessed in chunks. It has overlapping regions to
* avoid wasting bytes at the end of chunks.
*/
@SuppressWarnings({"rawtypes", "unchecked", "restriction"})
public class MappedFile extends AbstractCloseableReferenceCounted {
static final boolean RETAIN = Jvm.getBoolean("mappedFile.retain");
private static final long DEFAULT_CAPACITY = 128L << 40;
private final RandomAccessFile raf;
private final FileChannel fileChannel;
private final long chunkSize;
private final long overlapSize;
private final List<MappedBytesStore> stores = new ArrayList<>();
private final long capacity;
private final File file;
private final String canonicalPath;
private final boolean readOnly;
private NewChunkListener newChunkListener = MappedFile::logNewChunk;
protected MappedFile( final File file,
final RandomAccessFile raf,
final long chunkSize,
final long overlapSize,
final long capacity,
final boolean readOnly) {
this.file = file;
try {
this.canonicalPath = file.getCanonicalPath().intern();
} catch (IOException ioe) {
throw new IllegalStateException("Unable to obtain the canonical path for " + file.getAbsolutePath(), ioe);
}
this.raf = raf;
this.fileChannel = raf.getChannel();
this.chunkSize = OS.mapAlign(chunkSize);
this.overlapSize = overlapSize > 0 && overlapSize < 64 << 10 ? chunkSize : OS.mapAlign(overlapSize);
this.capacity = capacity;
this.readOnly = readOnly;
Jvm.doNotCloseOnInterrupt(getClass(), this.fileChannel);
}
private static void logNewChunk(final String filename,
final int chunk,
final long delayMicros) {
if (delayMicros < 100 || !Jvm.isDebugEnabled(MappedFile.class))
return;
// avoid a GC while trying to memory map.
final String message = BytesInternal.acquireStringBuilder()
.append("Allocation of ").append(chunk)
.append(" chunk in ").append(filename)
.append(" took ").append(delayMicros / 1e3).append(" ms.")
.toString();
Jvm.perf().on(MappedFile.class, message);
}
public static MappedFile of( final File file,
final long chunkSize,
final long overlapSize,
final boolean readOnly) throws FileNotFoundException {
// if (readOnly && OS.isWindows()) {
// Jvm.warn().on(MappedFile.class, "Read only mode not supported on Windows, defaulting to read/write");
// readOnly = false;
// }
RandomAccessFile raf = new CleaningRandomAccessFile(file, readOnly ? "r" : "rw");
// try {
final long capacity = /*readOnly ? raf.length() : */DEFAULT_CAPACITY;
return new MappedFile(file, raf, chunkSize, overlapSize, capacity, readOnly);
/*
} catch (IOException e) {
Closeable.closeQuietly(raf);
FileNotFoundException fnfe = new FileNotFoundException("Unable to open " + file);
fnfe.initCause(e);
throw fnfe;
}
*/
}
public static MappedFile mappedFile( final File file, final long chunkSize) throws FileNotFoundException {
return mappedFile(file, chunkSize, OS.pageSize());
}
/*
private void check(Throwable throwable, int[] count) {
for (int i = 0; i < stores.size(); i++) {
WeakReference<MappedBytesStore> storeRef = stores.get(i);
if (storeRef == null)
continue;
MappedBytesStore mbs = storeRef.get();
if (mbs != null && mbs.refCount() > 0) {
mbs.releaseLast();
throwable.printStackTrace();
count[0]++;
}
}
}
*/
public static MappedFile mappedFile( final String filename, final long chunkSize) throws FileNotFoundException {
return mappedFile(filename, chunkSize, OS.pageSize());
}
public static MappedFile mappedFile( final String filename,
final long chunkSize,
final long overlapSize) throws FileNotFoundException {
return mappedFile(new File(filename), chunkSize, overlapSize);
}
public static MappedFile mappedFile( final File file,
final long chunkSize,
final long overlapSize) throws FileNotFoundException {
return mappedFile(file, chunkSize, overlapSize, false);
}
public static MappedFile mappedFile( final File file,
final long chunkSize,
final long overlapSize,
final boolean readOnly) throws FileNotFoundException {
return MappedFile.of(file, chunkSize, overlapSize, readOnly);
}
public static MappedFile readOnly( final File file) throws FileNotFoundException {
long chunkSize = file.length();
long overlapSize = 0;
// Chunks of 4 GB+ not supported on Windows.
if (OS.isWindows() && chunkSize > 2L << 30) {
chunkSize = 2L << 30;
overlapSize = OS.pageSize();
}
return MappedFile.of(file, chunkSize, overlapSize, true);
}
public static MappedFile mappedFile( final File file,
final long capacity,
final long chunkSize,
final long overlapSize,
final boolean readOnly) throws IOException {
final RandomAccessFile raf = new CleaningRandomAccessFile(file, readOnly ? "r" : "rw");
// Windows throws an exception when setting the length when you re-open
if (raf.length() < capacity)
raf.setLength(capacity);
return new MappedFile(file, raf, chunkSize, overlapSize, capacity, readOnly);
}
public static void warmup() {
final List<IOException> errorsDuringWarmup = new ArrayList<>();
try {
Jvm.setExceptionHandlers(Slf4jExceptionHandler.FATAL, null, null);
final File file = File.createTempFile("delete_warming_up", "me");
file.deleteOnExit();
final long mapAlignment = OS.mapAlignment();
final int chunks = 64;
final int compileThreshold = Jvm.compileThreshold();
for (int j = 0; j <= compileThreshold; j += chunks) {
try {
try ( RandomAccessFile raf = new CleaningRandomAccessFile(file, "rw")) {
try (final MappedFile mappedFile = new MappedFile(file, raf, mapAlignment, 0, mapAlignment * chunks, false)) {
warmup0(mapAlignment, chunks, mappedFile);
}
}
Thread.yield();
} catch (IOException e) {
errorsDuringWarmup.add(e);
}
}
Thread.yield();
Files.delete(file.toPath());
} catch (IOException e) {
Jvm.resetExceptionHandlers();
Jvm.warn().on(MappedFile.class, "Error during warmup", e);
} finally {
Jvm.resetExceptionHandlers();
if (errorsDuringWarmup.size() > 0)
Jvm.warn().on(MappedFile.class, errorsDuringWarmup.size() + " errors during warmup: " + errorsDuringWarmup);
}
}
private static void warmup0(final long mapAlignment,
final int chunks,
final MappedFile mappedFile) throws IOException {
ReferenceOwner warmup = ReferenceOwner.temporary("warmup");
for (int i = 0; i < chunks; i++) {
mappedFile.acquireBytesForRead(warmup, i * mapAlignment)
.release(warmup);
mappedFile.acquireBytesForWrite(warmup, i * mapAlignment)
.release(warmup);
}
}
public File file() {
return file;
}
/**
* @throws IllegalStateException if closed.
*/
public MappedBytesStore acquireByteStore(
ReferenceOwner owner,
final long position)
throws IOException, IllegalArgumentException, IllegalStateException {
return acquireByteStore(owner, position, null, readOnly ? ReadOnlyMappedBytesStore::new : MappedBytesStore::new);
}
public MappedBytesStore acquireByteStore(
ReferenceOwner owner,
final long position,
BytesStore oldByteStore)
throws IOException, IllegalArgumentException, IllegalStateException {
return acquireByteStore(owner, position, oldByteStore, readOnly ? ReadOnlyMappedBytesStore::new : MappedBytesStore::new);
}
public MappedBytesStore acquireByteStore(
ReferenceOwner owner,
final long position,
BytesStore oldByteStore,
final MappedBytesStoreFactory mappedBytesStoreFactory)
throws IOException,
IllegalArgumentException,
IllegalStateException {
throwExceptionIfClosed();
if (position < 0)
throw new IOException("Attempt to access a negative position: " + position);
final int chunk = (int) (position / chunkSize);
Jvm.safepoint();
final MappedBytesStore mbs;
synchronized (stores) {
while (stores.size() <= chunk)
stores.add(null);
mbs = stores.get(chunk);
}
if (mbs != null) {
// don't reserve it again if we are already holding it.
if (mbs == oldByteStore) {
return mbs;
}
if (mbs.tryReserve(owner)) {
return mbs;
}
}
// its important we perform this outside the synchronized below, as this operation can take a while and if synchronized can block slow tailer
// from acquiring the next block
resizeRafIfTooSmall(chunk);
synchronized (stores) {
// We are back, protected by synchronized, and need to
// update our view on previous existence (we might have been stalled
// for a long time since we last checked dues to resizing and another
// thread might have added a MappedByteStore (very unlikely but still possible))
final MappedBytesStore mbs1 = stores.get(chunk);
if (mbs1 != null && mbs1.tryReserve(owner)) {
return mbs1;
}
// *** THIS CAN TAKE A LONG TIME IF A RESIZE HAS TO OCCUR ***
// let double check it to make sure no other thread change it in the meantime.
//resizeRafIfTooSmall(chunk);
final long mappedSize = chunkSize + overlapSize;
final MapMode mode = readOnly ? MapMode.READ_ONLY : MapMode.READ_WRITE;
final long startOfMap = chunk * chunkSize;
final long beginNs = System.nanoTime();
final long address = OS.map(fileChannel, mode, startOfMap, mappedSize);
final MappedBytesStore mbs2 = mappedBytesStoreFactory.create(owner, this, chunk * this.chunkSize, address, mappedSize, this.chunkSize);
if (RETAIN)
mbs2.reserve(this);
stores.set(chunk, mbs2);
final long elapsedNs = System.nanoTime() - beginNs;
if (newChunkListener != null)
newChunkListener.onNewChunk(file.getPath(), chunk, elapsedNs / 1000);
if (elapsedNs >= 2_000_000L)
Jvm.perf().on(getClass(), "Took " + elapsedNs / 1_000_000L + " ms to add mapping for " + file());
return mbs2;
}
}
private void resizeRafIfTooSmall(final int chunk) throws IOException {
Jvm.safepoint();
final long minSize = (chunk + 1L) * chunkSize + overlapSize;
long size = fileChannel.size();
Jvm.safepoint();
if (size >= minSize || readOnly)
return;
// handle a possible race condition between processes.
try {
// A single JVM cannot lock a distinct canonical file more than once.
// We might have several MappedFile objects that maps to
// the same underlying file (possibly via hard or soft links)
// so we use the canonical path as a lock key
// Ensure exclusivity for any and all MappedFile objects handling
// the same canonical file.
synchronized (canonicalPath) {
size = fileChannel.size();
if (size < minSize) {
final long beginNs = System.nanoTime();
try (FileLock ignore = fileChannel.lock()) {
size = fileChannel.size();
if (size < minSize) {
Jvm.safepoint();
raf.setLength(minSize);
Jvm.safepoint();
}
}
final long elapsedNs = System.nanoTime() - beginNs;
if (elapsedNs >= 1_000_000L) {
Jvm.perf().on(getClass(), "Took " + elapsedNs / 1000L + " us to grow file " + file());
}
}
}
} catch (IOException ioe) {
throw new IOException("Failed to resize to " + minSize, ioe);
}
}
/**
* Convenience method so you don't need to release the BytesStore
*/
public Bytes acquireBytesForRead(ReferenceOwner owner, final long position)
throws IOException, IllegalStateException, IllegalArgumentException {
throwExceptionIfClosed();
final MappedBytesStore mbs = acquireByteStore(owner, position, null);
final Bytes bytes = mbs.bytesForRead();
bytes.readPositionUnlimited(position);
bytes.reserveTransfer(INIT, owner);
mbs.release(owner);
return bytes;
}
public void acquireBytesForRead(ReferenceOwner owner, final long position, final VanillaBytes bytes)
throws IOException, IllegalStateException, IllegalArgumentException {
throwExceptionIfClosed();
final MappedBytesStore mbs = acquireByteStore(owner, position, null);
bytes.bytesStore(mbs, position, mbs.capacity() - position);
}
public Bytes acquireBytesForWrite(ReferenceOwner owner, final long position)
throws IOException, IllegalStateException, IllegalArgumentException {
throwExceptionIfClosed();
MappedBytesStore mbs = acquireByteStore(owner, position, null);
Bytes bytes = mbs.bytesForWrite();
bytes.writePosition(position);
bytes.reserveTransfer(INIT, owner);
mbs.release(owner);
return bytes;
}
public void acquireBytesForWrite(ReferenceOwner owner, final long position, final VanillaBytes bytes)
throws IOException, IllegalStateException, IllegalArgumentException {
throwExceptionIfClosed();
final MappedBytesStore mbs = acquireByteStore(owner, position, null);
bytes.bytesStore(mbs, position, mbs.capacity() - position);
bytes.writePosition(position);
}
@Override
protected boolean performReleaseInBackground() {
// don't perform the close in the background as that just sets a flag. This does the real work.
return true;
}
protected void performRelease() {
try {
synchronized (stores) {
for (int i = 0; i < stores.size(); i++) {
final MappedBytesStore mbs = stores.get(i);
if (mbs != null && RETAIN) {
// this MappedFile is the only referrer to the MappedBytesStore at this point,
// so ensure that it is released
mbs.release(this);
}
// Dereference released entities
stores.set(i, null);
}
}
} finally {
closeQuietly(raf);
setClosed();
}
}
public String referenceCounts() {
final StringBuilder sb = new StringBuilder();
sb.append("refCount: ").append(refCount());
for ( final MappedBytesStore mbs : stores) {
long count = 0;
if (mbs != null)
count = mbs.refCount();
sb.append(", ").append(count);
}
return sb.toString();
}
public long capacity() {
return capacity;
}
public long chunkSize() {
return chunkSize;
}
public long overlapSize() {
return overlapSize;
}
public NewChunkListener getNewChunkListener() {
return newChunkListener;
}
public void setNewChunkListener(final NewChunkListener listener) {
throwExceptionIfClosedInSetter();
this.newChunkListener = listener;
}
public long actualSize() throws IORuntimeException {
boolean interrupted = Thread.interrupted();
try {
return fileChannel.size();
// this was seen once deep in the JVM.
} catch (ArrayIndexOutOfBoundsException aiooe) {
// try again.
return actualSize();
} catch (ClosedByInterruptException cbie) {
close();
interrupted = true;
throw new IllegalStateException(cbie);
} catch (IOException e) {
final boolean open = fileChannel.isOpen();
if (open) {
throw new IORuntimeException(e);
} else {
close();
throw new IllegalStateException(e);
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
public RandomAccessFile raf() {
return raf;
}
@Override
protected void finalize() throws Throwable {
warnAndReleaseIfNotReleased();
super.finalize();
}
@Override
protected boolean threadSafetyCheck(boolean isUsed) {
// component is thread safe
return true;
}
}

@ -1,99 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.IOTools;
import net.openhft.chronicle.core.io.ReferenceOwner;
import net.openhft.chronicle.core.time.SystemTimeProvider;
import net.openhft.chronicle.core.time.TimeProvider;
import java.io.IOException;
/**
* Timestamps are unique across threads/processes on a single machine.
*
* @deprecated Use {@link MappedUniqueTimeProvider} instead.
*/
@Deprecated(/* to be removed in x.23 */)
public enum MappedUniqueMicroTimeProvider implements TimeProvider {
INSTANCE;
private static final int LAST_TIME = 128;
private final MappedFile file;
@SuppressWarnings("rawtypes")
private final Bytes bytes;
private TimeProvider provider = SystemTimeProvider.INSTANCE;
MappedUniqueMicroTimeProvider() {
try {
String user = System.getProperty("user.name", "unknown");
file = MappedFile.mappedFile(OS.TMP + "/.time-stamp." + user + ".dat", OS.pageSize(), 0);
IOTools.unmonitor(file);
ReferenceOwner mumtp = ReferenceOwner.temporary("mumtp");
bytes = file.acquireBytesForWrite(mumtp, 0);
bytes.append8bit("&TSF\nTime stamp file uses for sharing a unique id\n");
IOTools.unmonitor(bytes);
} catch (IOException ioe) {
throw new IORuntimeException(ioe);
}
}
public MappedUniqueMicroTimeProvider provider(TimeProvider provider) {
this.provider = provider;
return this;
}
@Override
public long currentTimeMillis() {
return provider.currentTimeMillis();
}
@Override
public long currentTimeMicros() {
long timeus = provider.currentTimeMicros();
while (true) {
long time0 = bytes.readVolatileLong(LAST_TIME);
long time0us = time0 / 1000;
long time;
if (time0us >= timeus)
time = (time0us + 1) * 1000;
else
time = timeus * 1000;
if (bytes.compareAndSwapLong(LAST_TIME, time0, time))
return time / 1_000;
Jvm.nanoPause();
}
}
@Override
public long currentTimeNanos() {
long time = provider.currentTimeNanos();
while (true) {
long time0 = bytes.readVolatileLong(LAST_TIME);
if (time0 >= time)
time = time0 + 1;
if (bytes.compareAndSwapLong(LAST_TIME, time0, time))
return time;
Jvm.nanoPause();
}
}
}

@ -1,104 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.IOTools;
import net.openhft.chronicle.core.io.ReferenceOwner;
import net.openhft.chronicle.core.time.SystemTimeProvider;
import net.openhft.chronicle.core.time.TimeProvider;
import java.io.IOException;
/**
* Timestamps are unique across threads/processes on a single machine.
*/
public enum MappedUniqueTimeProvider implements TimeProvider {
INSTANCE;
private static final int LAST_TIME = 128;
private final MappedFile file;
@SuppressWarnings("rawtypes")
private final Bytes bytes;
private TimeProvider provider = SystemTimeProvider.INSTANCE;
MappedUniqueTimeProvider() {
try {
String user = System.getProperty("user.name", "unknown");
file = MappedFile.mappedFile(OS.TMP + "/.time-stamp." + user + ".dat", OS.pageSize(), 0);
IOTools.unmonitor(file);
ReferenceOwner mumtp = ReferenceOwner.temporary("mumtp");
bytes = file.acquireBytesForWrite(mumtp, 0);
bytes.append8bit("&TSF\nTime stamp file uses for sharing a unique id\n");
IOTools.unmonitor(bytes);
} catch (IOException ioe) {
throw new IORuntimeException(ioe);
}
}
public MappedUniqueTimeProvider provider(TimeProvider provider) {
this.provider = provider;
return this;
}
@Override
public long currentTimeMillis() {
return provider.currentTimeMillis();
}
@Override
public long currentTimeMicros() {
long timeus = provider.currentTimeMicros();
while (true) {
long time0 = bytes.readVolatileLong(LAST_TIME);
long time0us = time0 / 1000;
long time;
if (time0us >= timeus)
time = (time0us + 1) * 1000;
else
time = timeus * 1000;
if (bytes.compareAndSwapLong(LAST_TIME, time0, time))
return time / 1_000;
Jvm.nanoPause();
}
}
@Override
public long currentTimeNanos() {
long time = provider.currentTimeNanos();
long time5 = time >>> 5;
long time0 = bytes.readVolatileLong(LAST_TIME);
long timeNanos5 = time0 >>> 5;
if (time5 > timeNanos5)
if (bytes.compareAndSwapLong(LAST_TIME, time0, time))
return time;
while (true) {
time0 = bytes.readVolatileLong(LAST_TIME);
long next = (time0 + 0x20) & ~0x1f;
if (bytes.compareAndSwapLong(LAST_TIME, time0, next))
return next;
Jvm.nanoPause();
}
}
}

@ -1,28 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
public interface MethodEncoder {
long messageId();
@SuppressWarnings("rawtypes")
void encode(Object[] objects, BytesOut out);
@SuppressWarnings("rawtypes")
Object[] decode(Object[] lastObjects, BytesIn in);
}

@ -1,61 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.util.Annotations;
import java.lang.reflect.Method;
import java.util.function.Function;
public enum MethodEncoderLookup implements Function<Method, MethodEncoder> {
BY_ANNOTATION;
@Override
public MethodEncoder apply(Method method) {
MethodId methodId = Annotations.getAnnotation(method, MethodId.class);
if (methodId == null) return null;
long messageId = methodId.value();
return new MethodEncoder() {
@Override
public long messageId() {
return messageId;
}
@SuppressWarnings("rawtypes")
@Override
public void encode(Object[] objects, BytesOut out) {
for (Object object : objects) {
if (object instanceof BytesMarshallable) {
((BytesMarshallable) object).writeMarshallable(out);
continue;
}
throw new IllegalArgumentException("Object type " + object + " not supported");
}
}
@SuppressWarnings("rawtypes")
@Override
public Object[] decode(Object[] lastObjects, BytesIn in) {
for (Object lastObject : lastObjects)
((BytesMarshallable) lastObject).readMarshallable(in);
return lastObjects;
}
};
}
}

@ -1,27 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MethodId {
long value();
}

@ -1,53 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
import net.openhft.chronicle.core.util.InvocationTargetRuntimeException;
public interface MethodReader extends Closeable {
String HISTORY = "history";
MethodReaderInterceptorReturns methodReaderInterceptorReturns();
/**
* Moves the queue to read a message if there is one, but is more expensive than {@link #lazyReadOne()}.
* If there is an exception in the dispatching mechanics then this should be caught and Jvm.warn'd.
* If there is an exception in the invocation then this is wrapped in a {@link InvocationTargetRuntimeException}
* and thrown.
*
* @return true if there was a message, false if no more messages.
* @throws InvocationTargetRuntimeException if the receiver (target method) throws
*/
boolean readOne() throws InvocationTargetRuntimeException;
/**
* Does a quick read which is simpler but might not read the next message. readOne() has to be called periodically.
* See also javadoc for {@link #readOne()}
*
* @return true if there was a message, false if there is probably not a message.
*/
default boolean lazyReadOne() {
return readOne();
}
/**
* Call close on the input when closed
*/
MethodReader closeIn(boolean closeIn);
}

@ -1,33 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
public interface MethodReaderBuilder {
default MethodReaderBuilder methodReaderInterceptor(MethodReaderInterceptor methodReaderInterceptor) {
return methodReaderInterceptorReturns((m, o, a, i) -> {
methodReaderInterceptor.intercept(m, o, a, i);
return null;
});
}
MethodReaderBuilder methodReaderInterceptorReturns(MethodReaderInterceptorReturns methodReaderInterceptorReturns);
MethodReaderBuilder warnMissing(boolean warnMissing);
MethodReader build(Object... components);
}

@ -1,30 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @deprecated Use {@link MethodReaderInterceptorReturns}
*/
@Deprecated(/* to be removed in x.22 */)
@FunctionalInterface
public interface MethodReaderInterceptor {
void intercept(Method m, Object o, Object[] args, Invocation invocation) throws InvocationTargetException;
}

@ -1,26 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@FunctionalInterface
public interface MethodReaderInterceptorReturns {
Object intercept(Method m, Object o, Object[] args, Invocation invocation) throws InvocationTargetException;
}

@ -1,48 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
import java.util.function.Supplier;
public interface MethodWriterBuilder<T> extends Supplier<T> {
MethodWriterBuilder<T> genericEvent(String genericEvent);
default MethodWriterBuilder<T> metaData(boolean metaData) {
return this;
}
@Deprecated(/* to be removed in x.23 */)
MethodWriterBuilder<T> useMethodIds(boolean useMethodIds);
MethodWriterBuilder<T> onClose(Closeable closeable);
// sourceId enables this, this isn't useful unless it's set.
@Deprecated(/* to be removed in x.22 */)
MethodWriterBuilder<T> recordHistory(boolean recordHistory);
default MethodWriterBuilder<T> updateInterceptor(UpdateInterceptor updateInterceptor) {
throw new UnsupportedOperationException();
}
default T build() {
return get();
}
}

@ -1,55 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.function.BiConsumer;
/**
* Invoked around method writing allowing you to take action before or after method invocation,
* or even not to call the method
*
* @deprecated Use MethodWriterInterceptorReturns
*/
@FunctionalInterface
@Deprecated(/* to be removed in x.22 */)
public interface MethodWriterInterceptor {
static MethodWriterInterceptor of( final MethodWriterListener methodWriterListener, final MethodWriterInterceptor interceptor) {
if (methodWriterListener == null && interceptor == null)
throw new IllegalArgumentException("both methodWriterListener and interceptor are NULL");
if (methodWriterListener == null)
return interceptor::intercept;
if (interceptor == null)
return (method, args, invoker) -> {
methodWriterListener.onWrite(method.getName(), args);
invoker.accept(method, args);
};
return (method, args, invoker) -> {
interceptor.intercept(method, args, invoker);
methodWriterListener.onWrite(method.getName(), args);
};
}
void intercept(Method method, Object[] args, BiConsumer<Method, Object[]> invoker);
}

@ -1,60 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method;
import java.util.function.BiFunction;
/*
* Peter Lawrey so interceptors can return an object to use for chaining.
* <p>
* Invoked around method writing allowing you to take action before or after method invocation,
* or even not to call the method
*/
@FunctionalInterface
public interface MethodWriterInterceptorReturns {
static MethodWriterInterceptorReturns of(MethodWriterInterceptor interceptor) {
return (m, a, i) -> {
interceptor.intercept(m, a, i::apply);
return null;
};
}
static MethodWriterInterceptorReturns of( final MethodWriterListener methodWriterListener, final MethodWriterInterceptorReturns interceptor) {
if (methodWriterListener == null && interceptor == null)
throw new IllegalArgumentException("both methodWriterListener and interceptor are NULL");
if (methodWriterListener == null)
return interceptor;
if (interceptor == null)
return (method, args, invoker) -> {
methodWriterListener.onWrite(method.getName(), args);
return invoker.apply(method, args);
};
return (method, args, invoker) -> {
methodWriterListener.onWrite(method.getName(), args);
return interceptor.intercept(method, args, invoker);
};
}
Object intercept(Method method, Object[] args, BiFunction<Method, Object[], Object> invoker);
}

@ -1,42 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationHandler;
public interface MethodWriterInvocationHandler extends InvocationHandler {
void recordHistory(boolean recordHistory);
void onClose(Closeable closeable);
default void methodWriterInterceptorReturns(MethodWriterListener methodWriterListener, MethodWriterInterceptorReturns interceptor) {
if (methodWriterListener != null || interceptor != null)
methodWriterInterceptorReturns(MethodWriterInterceptorReturns.of(methodWriterListener, interceptor));
}
void methodWriterInterceptorReturns(MethodWriterInterceptorReturns methodWriterInterceptor);
void genericEvent(String genericEvent);
void useMethodIds(boolean useMethodIds);
}

@ -1,29 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
/**
* Invoked before writing out this method and args.
*
* @deprecated Use MethodWriterInterceptorReturns
*/
@Deprecated(/* to be removed in x.22 */)
@FunctionalInterface
public interface MethodWriterListener {
void onWrite(String name, Object[] args);
}

@ -1,37 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
public interface MultiReaderBytesRingBuffer extends BytesRingBuffer {
default RingBufferReader createReader() {
return createReader(0);
}
/**
* Create a reader
*
* @param id of reader as each reader has separate read position etc.
* @return reader
*/
RingBufferReader createReader(int id);
}

@ -1,409 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.util.DecoratedBufferOverflowException;
import net.openhft.chronicle.core.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import static net.openhft.chronicle.bytes.NativeBytesStore.nativeStoreWithFixedCapacity;
import static net.openhft.chronicle.bytes.NoBytesStore.noBytesStore;
/**
* Elastic memory accessor which can wrap either a ByteBuffer or malloc'ed memory.
* <p>
* <p>This class can wrap <i>heap</i> ByteBuffers, called <i>Native</i>Bytes for historical reasons.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class NativeBytes<Underlying>
extends VanillaBytes<Underlying> {
private static final boolean BYTES_GUARDED = Jvm.getBoolean("bytes.guarded");
private static boolean s_newGuarded = BYTES_GUARDED;
private final long capacity;
public NativeBytes( final BytesStore store, final long capacity) throws IllegalStateException {
super(store, 0, capacity);
this.capacity = capacity;
}
public NativeBytes( final BytesStore store) throws IllegalStateException {
super(store, 0, store.capacity());
capacity = store.capacity();
}
/**
* For testing
*
* @return will new NativeBytes be guarded.
*/
public static boolean areNewGuarded() {
return s_newGuarded;
}
/**
* turn guarding on/off. Can be enabled by assertion with
* <code>
* assert NativeBytes.setNewGuarded(true);
* </code>
*
* @param guarded turn on if true
*/
public static boolean setNewGuarded(final boolean guarded) {
s_newGuarded = guarded;
return true;
}
/**
* For testing
*/
public static void resetNewGuarded() {
s_newGuarded = BYTES_GUARDED;
}
public static NativeBytes<Void> nativeBytes() {
try {
return NativeBytes.wrapWithNativeBytes(noBytesStore(), Bytes.MAX_CAPACITY);
} catch (IllegalStateException e) {
throw new AssertionError(e);
}
}
public static NativeBytes<Void> nativeBytes(final long initialCapacity) throws IllegalArgumentException {
final NativeBytesStore<Void> store = nativeStoreWithFixedCapacity(initialCapacity);
try {
try {
return NativeBytes.wrapWithNativeBytes(store, Bytes.MAX_CAPACITY);
} finally {
store.release(INIT);
}
} catch (IllegalStateException e) {
throw new AssertionError(e);
}
}
public static BytesStore<Bytes<Void>, Void> copyOf( final Bytes bytes) {
final long remaining = bytes.readRemaining();
try {
final NativeBytes<Void> bytes2 = Bytes.allocateElasticDirect(remaining);
bytes2.write(bytes, 0, remaining);
return bytes2;
} catch (IllegalArgumentException | BufferOverflowException | BufferUnderflowException e) {
throw new AssertionError(e);
}
}
private static long alignToPageSize(final long size) {
long mask = OS.pageSize() - 1;
return (size + mask) & ~mask;
}
public static <T> NativeBytes<T> wrapWithNativeBytes( final BytesStore<?, T> bs, long capacity) {
return s_newGuarded
? new GuardedNativeBytes(bs, capacity)
: new NativeBytes<>(bs, capacity);
}
protected static <T> long maxCapacityFor( BytesStore<?, T> bs) {
return bs.underlyingObject() instanceof ByteBuffer
|| bs.underlyingObject() instanceof byte[]
? MAX_HEAP_CAPACITY
: Bytes.MAX_CAPACITY;
}
@Override
public long capacity() {
return capacity;
}
@Override
protected void writeCheckOffset(final long offset, final long adding) throws BufferOverflowException {
if (offset >= bytesStore.start()) {
final long writeEnd = offset + adding;
if (writeEnd <= bytesStore.safeLimit()) {
return; // do nothing.
}
if (writeEnd >= capacity)
throw new BufferOverflowException(/*"Write exceeds capacity"*/);
checkResize(writeEnd);
} else {
throw new BufferOverflowException();
}
}
@Override
void prewriteCheckOffset(long offset, long subtracting) throws BufferOverflowException {
if (offset - subtracting >= bytesStore.start()) {
if (offset <= bytesStore.safeLimit()) {
return; // do nothing.
}
if (offset >= capacity)
throw new BufferOverflowException(/*"Write exceeds capacity"*/);
checkResize(offset);
} else {
throw new BufferOverflowException();
}
}
@Override
public void ensureCapacity(final long size) throws IllegalArgumentException {
try {
assert size >= 0;
writeCheckOffset(writePosition(), size);
} catch (BufferOverflowException e) {
IllegalArgumentException iae = new IllegalArgumentException("Bytes cannot be resized to " + size + " limit: " + capacity());
iae.printStackTrace();
throw iae;
}
}
private void checkResize(final long endOfBuffer) throws BufferOverflowException {
if (isElastic())
resize(endOfBuffer);
else
throw new BufferOverflowException();
}
@Override
public boolean isElastic() {
return true;
}
// the endOfBuffer is the minimum capacity and one byte more than the last addressable byte.
private void resize(final long endOfBuffer)
throws BufferOverflowException {
throwExceptionIfReleased();
if (endOfBuffer < 0)
throw new DecoratedBufferOverflowException(endOfBuffer + "< 0");
if (endOfBuffer > capacity())
throw new DecoratedBufferOverflowException(endOfBuffer + ">" + capacity());
final long realCapacity = realCapacity();
if (endOfBuffer <= realCapacity) {
// System.out.println("no resize " + endOfBuffer + " < " + realCapacity);
return;
}
// Grow by 50%
long size = Math.max(endOfBuffer + 7, realCapacity * 3 / 2 + 32);
if (isDirectMemory() || size > MAX_HEAP_CAPACITY) {
// Allocate direct memory of page granularity
size = alignToPageSize(size);
} else {
size &= ~0x7;
}
// Cap the size with capacity() again
size = Math.min(size, capacity());
final boolean isByteBufferBacked = bytesStore.underlyingObject() instanceof ByteBuffer;
if (isByteBufferBacked && size > MAX_HEAP_CAPACITY) {
// Add a stack trace to this relatively unusual event which will
// enable tracing of potentially derailed code or excessive buffer use.
final StackTrace stackTrace = new StackTrace();
final String stack = BytesUtil.asString("Calling stack is", stackTrace);
Jvm.warn().on(getClass(), "Going to try to replace ByteBuffer-backed BytesStore with " +
"raw NativeBytesStore to grow to " + size / 1024 + " KB. If later it is assumed that " +
"this bytes' underlyingObject() is ByteBuffer, NullPointerException is likely to be thrown. " +
stack);
}
// System.out.println("resize " + endOfBuffer + " to " + size);
if (endOfBuffer > 1 << 20)
Jvm.warn().on(getClass(), "Resizing buffer was " + realCapacity / 1024 + " KB, " +
"needs " + (endOfBuffer - realCapacity) + " bytes more, " +
"new-size " + size / 1024 + " KB");
final BytesStore store;
int position = 0;
try {
if (isByteBufferBacked && size <= MAX_HEAP_CAPACITY) {
position = ((ByteBuffer) bytesStore.underlyingObject()).position();
store = allocateNewByteBufferBackedStore(Maths.toInt32(size));
} else {
store = NativeBytesStore.lazyNativeBytesStoreWithFixedCapacity(size);
}
store.reserveTransfer(INIT, this);
} catch (IllegalArgumentException e) {
BufferOverflowException boe = new BufferOverflowException();
boe.initCause(e);
throw boe;
}
throwExceptionIfReleased();
final BytesStore<Bytes<Underlying>, Underlying> tempStore = this.bytesStore;
this.bytesStore.copyTo(store);
this.bytesStore(store);
try {
tempStore.release(this);
} catch (IllegalStateException e) {
Jvm.debug().on(getClass(), e);
}
if (this.bytesStore.underlyingObject() instanceof ByteBuffer) {
final ByteBuffer byteBuffer = (ByteBuffer) this.bytesStore.underlyingObject();
byteBuffer.position(0);
byteBuffer.limit(byteBuffer.capacity());
byteBuffer.position(position);
}
}
private BytesStore allocateNewByteBufferBackedStore(final int size) {
if (isDirectMemory()) {
return NativeBytesStore.elasticByteBuffer(size, capacity());
} else {
return HeapBytesStore.wrap(ByteBuffer.allocate(size));
}
}
@Override
public Bytes<Underlying> write( final byte[] bytes,
final int offset,
final int length) throws BufferOverflowException, IllegalArgumentException {
if (length > writeRemaining())
throw new BufferOverflowException();
ensureCapacity(length);
super.write(bytes, offset, length);
return this;
}
public Bytes<Underlying> write( final BytesStore bytes,
final long offset,
final long length) throws BufferOverflowException, IllegalArgumentException, BufferUnderflowException {
ensureCapacity(length);
super.write(bytes, offset, length);
return this;
}
@Override
public NativeBytes writeSome( final Bytes bytes) {
try {
long length = Math.min(bytes.readRemaining(), writeRemaining());
if (length + writePosition() >= 1 << 20)
length = Math.min(bytes.readRemaining(), realCapacity() - writePosition());
final long offset = bytes.readPosition();
ensureCapacity(length);
optimisedWrite(bytes, offset, length);
if (length == bytes.readRemaining()) {
bytes.clear();
} else {
bytes.readSkip(length);
if (bytes.writePosition() > bytes.realCapacity() / 2)
bytes.compact();
}
return this;
} catch (IllegalArgumentException | BufferUnderflowException | BufferOverflowException e) {
throw new AssertionError(e);
}
}
@Override
protected long writeOffsetPositionMoved(final long adding, final long advance) throws BufferOverflowException {
final long oldPosition = writePosition;
if (writePosition < bytesStore.start())
throw new BufferOverflowException();
final long writeEnd = writePosition + adding;
if (writeEnd > writeLimit)
throwBeyondWriteLimit(advance, writeEnd);
else if (writeEnd > bytesStore.safeLimit())
checkResize(writeEnd);
this.writePosition = writePosition + advance;
return oldPosition;
}
private void throwBeyondWriteLimit(long advance, long writeEnd) {
throw new DecoratedBufferOverflowException("attempt to write " + advance + " bytes to " + writeEnd + " limit: " + writeLimit);
}
@Override
public Bytes<Underlying> writeByte(final byte i8) throws BufferOverflowException {
final long offset = writeOffsetPositionMoved(1, 1);
bytesStore.writeByte(offset, i8);
return this;
}
@Override
public Bytes<Underlying> write8bit( final BytesStore bs) throws BufferOverflowException {
if (bs == null) {
writeStopBit(-1);
} else {
final long offset = bs.readPosition();
final long readRemaining = Math.min(writeRemaining(), bs.readLimit() - offset);
writeStopBit(readRemaining);
write(bs, offset, readRemaining);
}
return this;
}
@Override
public Bytes<Underlying> writeLong(final long i64) throws BufferOverflowException {
final long offset = writeOffsetPositionMoved(8L, 8L);
bytesStore.writeLong(offset, i64);
return this;
}
@Override
public long readRemaining() {
return writePosition - readPosition;
}
public final static class NativeSubBytes extends SubBytes {
private final NativeBytesStore nativeBytesStore;
public NativeSubBytes( final BytesStore bytesStore,
final long start,
final long capacity) throws IllegalStateException {
super(bytesStore, start, capacity);
nativeBytesStore = (NativeBytesStore) this.bytesStore;
}
@Override
public long read(final long offsetInRDI,
final byte[] bytes,
final int offset,
final int length) {
final int len = (int) Math.min(length, readLimit() - offsetInRDI);
int i;
final long address = nativeBytesStore.address + nativeBytesStore.translate(offsetInRDI);
for (i = 0; i < len - 7; i += 8)
UnsafeMemory.unsafePutLong(bytes, i, nativeBytesStore.memory.readLong(address + i));
if (i < len - 3) {
UnsafeMemory.unsafePutInt(bytes, i, nativeBytesStore.memory.readInt(address + i));
i += 4;
}
for (; i < len; i++)
UnsafeMemory.unsafePutByte(bytes, i, nativeBytesStore.memory.readByte(address + i));
return len;
}
}
}

@ -1,852 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.*;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.cleaner.CleanerServiceLocator;
import net.openhft.chronicle.core.cleaner.spi.ByteBufferCleanerService;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.util.SimpleCleaner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import static net.openhft.chronicle.bytes.Bytes.MAX_CAPACITY;
@SuppressWarnings({"restriction", "rawtypes", "unchecked"})
public class NativeBytesStore<Underlying>
extends AbstractBytesStore<NativeBytesStore<Underlying>, Underlying> {
private static final long MEMORY_MAPPED_SIZE = 128 << 10;
private static final Field BB_ADDRESS, BB_CAPACITY, BB_ATT;
private static final ByteBufferCleanerService CLEANER_SERVICE = CleanerServiceLocator.cleanerService();
// static MappedBytes last;
static {
Class directBB = ByteBuffer.allocateDirect(0).getClass();
BB_ADDRESS = Jvm.getField(directBB, "address");
BB_CAPACITY = Jvm.getField(directBB, "capacity");
BB_ATT = Jvm.getField(directBB, "att");
}
protected long address;
// on release, set this to null.
protected Memory memory = OS.memory();
protected long limit, maximumLimit;
private SimpleCleaner cleaner;
private boolean elastic;
private Underlying underlyingObject;
private final Finalizer finalizer;
private NativeBytesStore() {
finalizer = null;
}
private NativeBytesStore( ByteBuffer bb, boolean elastic) {
this(bb, elastic, Bytes.MAX_HEAP_CAPACITY);
}
public NativeBytesStore( ByteBuffer bb, boolean elastic, int maximumLimit) {
this();
init(bb, elastic);
this.maximumLimit = elastic ? maximumLimit : Math.min(limit, maximumLimit);
}
public NativeBytesStore(
long address, long limit) {
this(address, limit, null, false);
}
public NativeBytesStore(
long address, long limit, Runnable deallocator, boolean elastic) {
this(address, limit, deallocator, elastic, false);
}
protected NativeBytesStore(
long address, long limit, Runnable deallocator, boolean elastic, boolean monitored) {
super(monitored);
setAddress(address);
this.limit = limit;
this.maximumLimit = elastic ? MAX_CAPACITY : limit;
this.cleaner = deallocator == null ? null : new SimpleCleaner(deallocator);
underlyingObject = null;
this.elastic = elastic;
if (cleaner == null)
finalizer = null;
else
finalizer = new Finalizer();
}
public static NativeBytesStore<ByteBuffer> wrap( ByteBuffer bb) {
return new NativeBytesStore<>(bb, false);
}
public static <T> NativeBytesStore<T> uninitialized() {
return new NativeBytesStore<>();
}
/**
* this is an elastic native store
*
* @param capacity of the buffer.
*/
public static NativeBytesStore<Void> nativeStore(long capacity)
throws IllegalArgumentException {
return of(capacity, true, true);
}
private static NativeBytesStore<Void> of(long capacity, boolean zeroOut, boolean elastic)
throws IllegalArgumentException {
if (capacity <= 0)
return new NativeBytesStore<>(NoBytesStore.NO_PAGE, 0, null, elastic);
Memory memory = OS.memory();
long address = memory.allocate(capacity);
if (zeroOut || capacity < MEMORY_MAPPED_SIZE) {
memory.setMemory(address, capacity, (byte) 0);
memory.storeFence();
}
Deallocator deallocator = new Deallocator(address, capacity);
return new NativeBytesStore<>(address, capacity, deallocator, elastic);
}
public static NativeBytesStore<Void> nativeStoreWithFixedCapacity(long capacity)
throws IllegalArgumentException {
return of(capacity, true, false);
}
public static NativeBytesStore<Void> lazyNativeBytesStoreWithFixedCapacity(long capacity)
throws IllegalArgumentException {
return of(capacity, false, false);
}
public static NativeBytesStore<ByteBuffer> elasticByteBuffer() {
return elasticByteBuffer(OS.pageSize(), MAX_CAPACITY);
}
public static NativeBytesStore<ByteBuffer> elasticByteBuffer(int size, long maxSize) {
return new NativeBytesStore<>(ByteBuffer.allocateDirect(size), true, Math.toIntExact(maxSize));
}
public static NativeBytesStore from( String text) {
return from(text.getBytes(StandardCharsets.ISO_8859_1));
}
public static NativeBytesStore from( byte[] bytes) {
try {
NativeBytesStore nbs = nativeStoreWithFixedCapacity(bytes.length);
Bytes<byte[]> bytes2 = Bytes.wrapForRead(bytes);
bytes2.copyTo(nbs);
bytes2.releaseLast();
return nbs;
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
}
@Override
public boolean isDirectMemory() {
return true;
}
@Override
public boolean canReadDirect(long length) {
return limit >= length;
}
public void init( ByteBuffer bb, boolean elastic) {
this.elastic = elastic;
underlyingObject = (Underlying) bb;
setAddress(Jvm.address(bb));
this.limit = bb.capacity();
}
public void uninit() {
underlyingObject = null;
address = 0;
limit = 0;
maximumLimit = 0;
cleaner = null;
}
@Override
public void move(long from, long to, long length) throws BufferUnderflowException {
if (from < 0 || to < 0) throw new BufferUnderflowException();
long address = this.address;
if (address == 0) throwException(null);
memoryCopyMemory(address + from, address + to, length);
}
private void memoryCopyMemory(long fromAddress, long toAddress, long length) {
try {
memory.copyMemory(fromAddress, toAddress, length);
} catch (NullPointerException ifReleased) {
throwException(ifReleased);
}
}
private void throwException(Throwable ifReleased) {
throwExceptionIfReleased();
throw new IllegalStateException(ifReleased);
}
@Override
public BytesStore<NativeBytesStore<Underlying>, Underlying> copy() {
try {
if (underlyingObject == null) {
NativeBytesStore<Void> copy = of(realCapacity(), false, true);
memoryCopyMemory(address, copy.address, capacity());
return (BytesStore) copy;
} else if (underlyingObject instanceof ByteBuffer) {
ByteBuffer bb = ByteBuffer.allocateDirect(Maths.toInt32(capacity()));
bb.put((ByteBuffer) underlyingObject);
bb.clear();
return (BytesStore) wrap(bb);
} else {
throw new UnsupportedOperationException();
}
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
}
@Override
public VanillaBytes<Underlying> bytesForWrite() throws IllegalStateException {
return elastic
? NativeBytes.wrapWithNativeBytes(this, this.capacity())
: new VanillaBytes<>(this);
}
@Override
@ForceInline
public long realCapacity() {
return limit;
}
@Override
@ForceInline
public long capacity() {
return maximumLimit;
}
@Override
@ForceInline
public Underlying underlyingObject() {
return underlyingObject;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> zeroOut(long start, long end) {
if (end <= start)
return this;
if (start < start())
start = start();
if (end > capacity())
end = capacity();
memory.setMemory(address + translate(start), end - start, (byte) 0);
return this;
}
@Override
@ForceInline
public boolean compareAndSwapInt(long offset, int expected, int value) {
return memory.compareAndSwapInt(address + translate(offset), expected, value);
}
@Override
public void testAndSetInt(long offset, int expected, int value) {
memory.testAndSetInt(address + translate(offset), offset, expected, value);
}
@Override
@ForceInline
public boolean compareAndSwapLong(long offset, long expected, long value) {
return memory.compareAndSwapLong(address + translate(offset), expected, value);
}
@Override
@ForceInline
public long addAndGetLong(long offset, long adding) throws BufferUnderflowException {
return memory.addLong(address + translate(offset), adding);
}
@Override
@ForceInline
public int addAndGetInt(long offset, int adding) throws BufferUnderflowException {
return memory.addInt(address + translate(offset), adding);
}
protected long translate(long offset) {
return offset;
}
@Override
@ForceInline
public byte readByte(long offset) {
return memory.readByte(address + translate(offset));
}
public int readUnsignedByte(long offset) throws BufferUnderflowException {
return readByte(offset) & 0xFF;
}
@Override
@ForceInline
public short readShort(long offset) {
return memory.readShort(address + translate(offset));
}
@Override
@ForceInline
public int readInt(long offset) {
return memory.readInt(address + translate(offset));
}
@Override
@ForceInline
public long readLong(long offset) {
long address = this.address;
assert address != 0;
return memory.readLong(address + translate(offset));
}
@Override
@ForceInline
public float readFloat(long offset) {
return memory.readFloat(address + translate(offset));
}
@Override
@ForceInline
public double readDouble(long offset) {
return memory.readDouble(address + translate(offset));
}
@Override
@ForceInline
public byte readVolatileByte(long offset) {
return memory.readVolatileByte(address + translate(offset));
}
@Override
@ForceInline
public short readVolatileShort(long offset) {
return memory.readVolatileShort(address + translate(offset));
}
@Override
@ForceInline
public int readVolatileInt(long offset) {
return memory.readVolatileInt(address + translate(offset));
}
@Override
@ForceInline
public long readVolatileLong(long offset) {
return memory.readVolatileLong(address + translate(offset));
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeByte(long offset, byte i8) {
memory.writeByte(address + translate(offset), i8);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeShort(long offset, short i16) {
memory.writeShort(address + translate(offset), i16);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeInt(long offset, int i32) {
try {
memory.writeInt(address + translate(offset), i32);
return this;
} catch (NullPointerException e) {
throwExceptionIfReleased();
throw e;
}
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeOrderedInt(long offset, int i) {
memory.writeOrderedInt(address + translate(offset), i);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeLong(long offset, long i64) {
memory.writeLong(address + translate(offset), i64);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeOrderedLong(long offset, long i) {
memory.writeOrderedLong(address + translate(offset), i);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeFloat(long offset, float f) {
memory.writeFloat(address + translate(offset), f);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeDouble(long offset, double d) {
memory.writeDouble(address + translate(offset), d);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeVolatileByte(long offset, byte i8) {
memory.writeVolatileByte(address + translate(offset), i8);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeVolatileShort(long offset, short i16) {
memory.writeVolatileShort(address + translate(offset), i16);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeVolatileInt(long offset, int i32) {
memory.writeVolatileInt(address + translate(offset), i32);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> writeVolatileLong(long offset, long i64) {
memory.writeVolatileLong(address + translate(offset), i64);
return this;
}
@Override
@ForceInline
public NativeBytesStore<Underlying> write(
long offsetInRDO, byte[] bytes, int offset, int length) {
memory.copyMemory(bytes, offset, address + translate(offsetInRDO), length);
return this;
}
@Override
@ForceInline
public void write(
long offsetInRDO, ByteBuffer bytes, int offset, int length) {
if (bytes.isDirect()) {
memoryCopyMemory(Jvm.address(bytes) + offset, address + translate(offsetInRDO), length);
} else {
memory.copyMemory(bytes.array(), offset, address + translate(offsetInRDO), length);
}
}
@Override
@ForceInline
public NativeBytesStore<Underlying> write(
long writeOffset, RandomDataInput bytes, long readOffset, long length)
throws BufferOverflowException, BufferUnderflowException {
if (bytes.isDirectMemory()) {
memoryCopyMemory(bytes.addressForRead(readOffset), addressForWrite(writeOffset), length);
} else {
write0(writeOffset, bytes, readOffset, length);
}
return this;
}
public void write0(long offsetInRDO, RandomDataInput bytes, long offset, long length) throws BufferUnderflowException {
long i = 0;
for (; i < length - 7; i += 8) {
writeLong(offsetInRDO + i, bytes.readLong(offset + i));
}
for (; i < length; i++) {
writeByte(offsetInRDO + i, bytes.readByte(offset + i));
}
}
@Override
public long addressForRead(long offset) throws BufferUnderflowException {
if (offset < start() || offset > realCapacity())
throw new BufferUnderflowException();
return address + translate(offset);
}
@Override
public long addressForWrite(long offset) throws BufferOverflowException {
if (offset < start() || offset > realCapacity())
throw new BufferOverflowException();
return address + translate(offset);
}
@Override
public long addressForWritePosition() throws UnsupportedOperationException, BufferOverflowException {
return addressForWrite(start());
}
@Override
protected void performRelease() {
memory = null;
if (cleaner != null) {
cleaner.clean();
} else if (underlyingObject instanceof ByteBuffer) {
ByteBuffer underlyingObject = (ByteBuffer) this.underlyingObject;
if (underlyingObject.isDirect())
CLEANER_SERVICE.clean(underlyingObject);
}
}
@Override
public String toString() {
try {
return BytesInternal.toString(this);
} catch (IllegalStateException e) {
return e.toString();
}
}
@Override
@ForceInline
public void nativeRead(long position, long address, long size) throws BufferUnderflowException {
// TODO add bounds checking.
memoryCopyMemory(addressForRead(position), address, size);
}
@Override
@ForceInline
public void nativeWrite(long address, long position, long size) throws BufferOverflowException {
// TODO add bounds checking.
memoryCopyMemory(address, addressForWrite(position), size);
}
void write8bit(long position, char[] chars, int offset, int length) {
long addr = address + translate(position);
Memory memory = this.memory;
for (int i = 0; i < length; i++)
memory.writeByte(addr + i, (byte) chars[offset + i]);
}
void read8bit(long position, char[] chars, int length) {
long addr = address + translate(position);
Memory memory = this.memory;
for (int i = 0; i < length; i++)
chars[i] = (char) (memory.readByte(addr + i) & 0xFF);
}
@Override
public long readIncompleteLong(long offset) {
int remaining = (int) Math.min(8, readRemaining() - offset);
long l = 0;
for (int i = 0; i < remaining; i++) {
byte b = memory.readByte(address + offset + i);
l |= (long) (b & 0xFF) << (i * 8);
}
return l;
}
@Override
public boolean equals(Object obj) {
return obj instanceof BytesStore && BytesInternal.contentEqual(this, (BytesStore) obj);
}
public void setAddress(long address) {
if ((address & ~0x3FFF) == 0)
throw new AssertionError("Invalid addressForRead " + Long.toHexString(address));
this.address = address;
}
@Deprecated(/* to be removed in x.22 */)
public long appendUTF(long pos, char[] chars, int offset, int length) throws BufferOverflowException {
return appendUtf8(pos, chars, offset, length);
}
public long appendUtf8(long pos, char[] chars, int offset, int length) throws BufferOverflowException {
if (pos + length > realCapacity())
throw new BufferOverflowException();
long address = this.address + translate(0);
Memory memory = this.memory;
if (memory == null) throw new NullPointerException();
int i;
ascii:
{
for (i = 0; i < length - 3; i += 4) {
final int i2 = offset + i;
char c0 = chars[i2];
char c1 = chars[i2 + 1];
char c2 = chars[i2 + 2];
char c3 = chars[i2 + 3];
if ((c0 | c1 | c2 | c3) > 0x007F)
break ascii;
final int value = (c0) | (c1 << 8) | (c2 << 16) | (c3 << 24);
UnsafeMemory.unsafePutInt(address + pos, value);
pos += 4;
}
for (; i < length; i++) {
char c = chars[offset + i];
if (c > 0x007F)
break ascii;
UnsafeMemory.unsafePutByte(address + pos++, (byte) c);
}
return pos;
}
return appendUtf8a(pos, chars, offset, length, i);
}
private long appendUtf8a(long pos, char[] chars, int offset, int length, int i) {
for (; i < length; i++) {
char c = chars[offset + i];
if (c <= 0x007F) {
writeByte(pos++, (byte) c);
} else if (c <= 0x07FF) {
writeByte(pos++, (byte) (0xC0 | ((c >> 6) & 0x1F)));
writeByte(pos++, (byte) (0x80 | c & 0x3F));
} else {
writeByte(pos++, (byte) (0xE0 | ((c >> 12) & 0x0F)));
writeByte(pos++, (byte) (0x80 | ((c >> 6) & 0x3F)));
writeByte(pos++, (byte) (0x80 | (c & 0x3F)));
}
}
return pos;
}
@Override
public long copyTo( BytesStore store) {
if (store.isDirectMemory())
return copyToDirect(store);
else
return super.copyTo(store);
}
public long copyToDirect( BytesStore store) {
long toCopy = Math.min(limit, store.safeLimit());
if (toCopy > 0) {
try {
long addr = address;
long addr2 = store.addressForWrite(0);
memoryCopyMemory(addr, addr2, toCopy);
} catch (BufferOverflowException e) {
throw new AssertionError(e);
}
}
return toCopy;
}
@Override
public ByteBuffer toTemporaryDirectByteBuffer() {
ByteBuffer bb = ByteBuffer.allocateDirect(0);
try {
BB_ADDRESS.setLong(bb, address);
BB_CAPACITY.setInt(bb, Maths.toUInt31(readRemaining()));
BB_ATT.set(bb, this);
} catch (Exception e) {
throw new AssertionError(e);
}
bb.clear();
return bb;
}
@Override
public int byteCheckSum() throws IORuntimeException {
return byteCheckSum(start(), readLimit());
}
public int byteCheckSum(long position, long limit) {
Memory memory = this.memory;
assert memory != null;
int b = 0;
long ptr = address + position;
long end = address + limit;
for (; ptr < end - 7; ptr += 8) {
b += memory.readByte(ptr)
+ memory.readByte(ptr + 1)
+ memory.readByte(ptr + 2)
+ memory.readByte(ptr + 3)
+ memory.readByte(ptr + 4)
+ memory.readByte(ptr + 5)
+ memory.readByte(ptr + 6)
+ memory.readByte(ptr + 7);
}
for (; ptr < end; ptr++) {
b += memory.readByte(ptr);
}
return b & 0xFF;
}
@Override
public boolean sharedMemory() {
return false;
}
@Override
public long read(long offsetInRDI, byte[] bytes, int offset, int length) {
int len = (int) Math.min(length, readLimit() - offsetInRDI);
int i;
final long address = this.address + translate(offsetInRDI);
for (i = 0; i < len - 7; i += 8)
UnsafeMemory.unsafePutLong(bytes, i, memory.readLong(address + i));
if (i < len - 3) {
UnsafeMemory.unsafePutInt(bytes, i, memory.readInt(address + i));
i += 4;
}
for (; i < len; i++)
UnsafeMemory.unsafePutByte(bytes, i, memory.readByte(address + i));
return len;
}
@Override
public int peekUnsignedByte(long offset) {
final long address = this.address;
final Memory memory = this.memory;
final long translate = translate(offset);
// assert translate >= 0;
final long address2 = address + translate;
// last.writeLong(8, Thread.currentThread().getId());
// last.writeLong(0, offset);
// last.writeLong(16, translate);
// last.writeLong(32, maximumLimit);
// last.writeLong(48, addressForRead);
// last.writeLong(64, address2);
// last.writeBoolean(80, memory != null);
// last.writeVolatileByte(88, (byte) 1);
int ret = translate >= limit ? -1 :
memory.readByte(address2) & 0xFF;
// last.writeVolatileByte(88, (byte) 0xFF);
// last.writeLong(24, Thread.currentThread().getId());
return ret;
}
@Override
public int fastHash(long offset, int length) throws BufferUnderflowException {
long ret;
switch (length) {
case 0:
return 0;
case 1:
ret = readByte(offset);
break;
case 2:
ret = readShort(offset);
break;
case 4:
ret = readInt(offset);
break;
case 8:
ret = readInt(offset) * 0x6d0f27bdL + readInt(offset + 4);
break;
default:
return super.fastHash(offset, length);
}
long hash = ret * 0x855dd4db;
return (int) (hash ^ (hash >> 32));
}
@Override
public long safeLimit() {
return limit;
}
static class Deallocator implements Runnable {
private volatile long address;
private final long size;
Deallocator(long address, long size) {
assert address != 0;
this.address = address;
this.size = size;
}
@Override
public void run() {
// System.out.println("Release " + Long.toHexString(addressForRead));
if (address == 0)
return;
long addressToFree = address;
address = 0;
OS.memory().freeMemory(addressToFree, size);
}
}
private class Finalizer {
@Override
protected void finalize() throws Throwable {
super.finalize();
warnAndReleaseIfNotReleased();
}
}
}

@ -1,24 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
@FunctionalInterface
public interface NewChunkListener {
void onNewChunk(String filename, int chunk, long delayMicros);
}

@ -1,338 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.io.IOTools;
import net.openhft.chronicle.core.io.ReferenceOwner;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* This is a ByteStore which uses no space but could be resized to be larger (by replacing it with a ByteStire with space)
*
* @see ReleasedBytesStore
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public enum NoBytesStore implements BytesStore {
NO_BYTES_STORE;
public static final long NO_PAGE;
public static final Bytes NO_BYTES;
static {
try {
NO_PAGE = OS.memory().allocate(OS.pageSize());
NO_BYTES = new VanillaBytes(noBytesStore());
IOTools.unmonitor(NO_BYTES);
} catch ( IllegalArgumentException | IllegalStateException e) {
throw new AssertionError(e);
}
}
public static <T, B extends BytesStore<B, T>> BytesStore<B, T> noBytesStore() {
return NO_BYTES_STORE;
}
@Override
public void reserve(ReferenceOwner owner) throws IllegalStateException {
}
@Override
public void release(ReferenceOwner owner) throws IllegalStateException {
}
@Override
public void releaseLast(ReferenceOwner id) throws IllegalStateException {
}
@Override
public int refCount() {
return 1;
}
@Override
public boolean tryReserve(ReferenceOwner owner) {
return false;
}
@Override
public boolean reservedBy(ReferenceOwner owner) {
return true;
}
@Override
public RandomDataOutput writeByte(long offset, byte i8) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeShort(long offset, short i) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeInt(long offset, int i) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeOrderedInt(long offset, int i) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeLong(long offset, long i) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeOrderedLong(long offset, long i) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeFloat(long offset, float d) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeDouble(long offset, double d) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeVolatileByte(long offset, byte i8) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeVolatileShort(long offset, short i16) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeVolatileInt(long offset, int i32) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput writeVolatileLong(long offset, long i64) {
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput write(long offsetInRDO, byte[] bytes, int offset, int length) {
if (length != 0)
throw new UnsupportedOperationException();
return this;
}
@Override
public void write(long offsetInRDO, ByteBuffer bytes, int offset, int length) {
if (length != 0)
throw new UnsupportedOperationException();
}
@Override
public RandomDataOutput write(long writeOffset, RandomDataInput bytes, long readOffset, long length) {
if (length != 0)
throw new UnsupportedOperationException();
return this;
}
@Override
public byte readByte(long offset) {
throw new UnsupportedOperationException();
}
@Override
public int peekUnsignedByte(long offset) {
return -1;
}
@Override
public short readShort(long offset) {
throw new UnsupportedOperationException();
}
@Override
public int readInt(long offset) {
throw new UnsupportedOperationException();
}
@Override
public long readLong(long offset) {
throw new UnsupportedOperationException();
}
@Override
public float readFloat(long offset) {
throw new UnsupportedOperationException();
}
@Override
public double readDouble(long offset) {
throw new UnsupportedOperationException();
}
@Override
public byte readVolatileByte(long offset) throws BufferUnderflowException {
throw new UnsupportedOperationException();
}
@Override
public short readVolatileShort(long offset) throws BufferUnderflowException {
throw new UnsupportedOperationException();
}
@Override
public int readVolatileInt(long offset) throws BufferUnderflowException {
throw new UnsupportedOperationException();
}
@Override
public long readVolatileLong(long offset) throws BufferUnderflowException {
throw new BufferUnderflowException();
}
@Override
public boolean isDirectMemory() {
return false;
}
@Override
public BytesStore copy() {
return this;
}
@Override
public long capacity() {
return 0;
}
@Override
public Void underlyingObject() {
return null;
}
@Override
public boolean inside(long offset) {
return false;
}
@Override
public boolean inside(long offset, long buffer) {
return false;
}
@Override
public long copyTo( BytesStore store) {
// nothing to copy.
return 0L;
}
@Override
public void nativeWrite(long address, long position, long size) {
throw new UnsupportedOperationException();
}
@Override
public void nativeRead(long position, long address, long size) {
throw new UnsupportedOperationException();
}
@Override
public boolean compareAndSwapInt(long offset, int expected, int value) {
throw new UnsupportedOperationException();
}
@Override
public void testAndSetInt(long offset, int expected, int value) {
throw new UnsupportedOperationException();
}
@Override
public boolean compareAndSwapLong(long offset, long expected, long value) {
throw new UnsupportedOperationException();
}
@Override
public boolean equalBytes( BytesStore bytesStore, long length) {
return length == 0;
}
@Override
public void move(long from, long to, long length) {
throw new UnsupportedOperationException();
}
@Override
public long addressForRead(long offset) throws BufferUnderflowException {
if (offset != 0)
throw new BufferUnderflowException();
return NO_PAGE;
}
@Override
public long addressForWrite(long offset) throws BufferOverflowException {
if (offset != 0)
throw new BufferOverflowException();
return NO_PAGE;
}
@Override
public long addressForWritePosition() throws UnsupportedOperationException, BufferOverflowException {
return NO_PAGE;
}
@Override
public Bytes bytesForWrite() {
throw new UnsupportedOperationException("todo");
}
@Override
public boolean sharedMemory() {
return false;
}
}

@ -1,24 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
@FunctionalInterface
public interface OffsetFormat {
@SuppressWarnings("rawtypes")
void append(long offset, Bytes bytes);
}

@ -1,103 +0,0 @@
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.util.DecoratedBufferOverflowException;
import net.openhft.chronicle.core.Jvm;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
public class OnHeapBytes extends VanillaBytes<byte[]> {
public static final int MAX_CAPACITY = Bytes.MAX_HEAP_CAPACITY;
private final boolean elastic;
private final long capacity;
public OnHeapBytes( BytesStore bytesStore, boolean elastic) throws IllegalStateException {
super(bytesStore);
this.elastic = elastic;
this.capacity = elastic ? MAX_CAPACITY : bytesStore.capacity();
writePosition(0);
writeLimit(capacity());
}
@Override
public long capacity() {
return capacity;
}
@Override
public boolean isElastic() {
return elastic;
}
@Override
protected void writeCheckOffset(long offset, long adding)
throws BufferOverflowException {
if (offset >= bytesStore.start()) {
long writeEnd = offset + adding;
if (writeEnd > writeLimit)
throwBeyondWriteLimit(adding, writeEnd);
if (writeEnd <= bytesStore.safeLimit()) {
return; // do nothing.
}
checkResize(writeEnd);
} else {
throw new BufferOverflowException();
}
}
private void throwBeyondWriteLimit(long advance, long writeEnd) {
throw new DecoratedBufferOverflowException("attempt to write " + advance + " bytes to " + writeEnd + " limit: " + writeLimit);
}
private void checkResize(long endOfBuffer)
throws BufferOverflowException {
if (isElastic())
resize(endOfBuffer);
else
throw new BufferOverflowException();
}
// the endOfBuffer is the minimum capacity and one byte more than the last addressable byte.
private void resize(long endOfBuffer)
throws BufferOverflowException {
if (endOfBuffer < 0)
throw new BufferOverflowException();
if (endOfBuffer > capacity())
throw new BufferOverflowException();
final long realCapacity = realCapacity();
if (endOfBuffer <= realCapacity) {
// System.out.println("no resize " + endOfBuffer + " < " + realCapacity);
return;
}
// Grow by 50%
long size0 = Math.max(endOfBuffer, realCapacity * 3 / 2);
// Size must not be more than capacity(), it may break some assumptions in BytesStore or elsewhere
int size = (int) Math.min(size0, capacity());
// System.out.println("resize " + endOfBuffer + " to " + size);
if (endOfBuffer > 1 << 20)
Jvm.warn().on(getClass(), "Resizing buffer was " + realCapacity / 1024 + " KB, " +
"needs " + (endOfBuffer - realCapacity) + " bytes more, " +
"new-size " + size / 1024 + " KB");
HeapBytesStore store;
try {
store = HeapBytesStore.wrap(new byte[size]);
store.reserveTransfer(INIT, this);
} catch (IllegalArgumentException e) {
BufferOverflowException boe = new BufferOverflowException();
boe.initCause(e);
throw boe;
}
BytesStore<Bytes<byte[]>, byte[]> tempStore = this.bytesStore;
this.bytesStore.copyTo(store);
this.bytesStore(store);
try {
tempStore.release(this);
} catch (IllegalStateException e) {
Jvm.debug().on(getClass(), e);
}
}
}

@ -1,55 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
/**
* A BytesStore which can point to arbitrary memory.
*/
public class PointerBytesStore extends NativeBytesStore<Void> {
private boolean isPresent = false;
public PointerBytesStore() {
super(NoBytesStore.NO_PAGE, 0, null, false, false);
}
public void set(long address, long capacity) {
isPresent = true;
setAddress(address);
this.limit = maximumLimit = capacity;
}
@Override
public VanillaBytes<Void> bytesForWrite() throws IllegalStateException {
return new VanillaBytes<>(this);
}
@Override
public long safeLimit() {
return limit;
}
@Override
public long start() {
return 0;
}
}

@ -1,207 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.io.ReferenceCounted;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteOrder;
interface RandomCommon extends ReferenceCounted {
/**
* @return The smallest position allowed in this buffer.
*/
@ForceInline
default long start() {
return 0L;
}
/**
* @return the highest limit allowed for this buffer.
*/
@ForceInline
default long capacity() {
return Bytes.MAX_CAPACITY;
}
/**
* @return the limit for this buffer without resizing
*/
default long realCapacity() {
return capacity();
}
/**
* The read position must be start() &lt;= readPosition() &amp;&amp; readPosition() &lt;= readLimit() &amp;&amp; readPosition &lt; safeLimit()
*
* @return position to read from.
*/
@ForceInline
default long readPosition() {
return start();
}
/**
* The read position must be readPosition() &lt;= writePosition() &amp;&amp; writePosition() &lt;= writeLimit()
*
* @return position to write to.
*/
@ForceInline
default long writePosition() {
return start();
}
/**
* @return How many more bytes can we read.
*/
@ForceInline
default long readRemaining() {
long remaining = readLimit() - readPosition();
return remaining;
}
/**
* @return How many more bytes can we written.
*/
@ForceInline
default long writeRemaining() {
return writeLimit() - writePosition();
}
/**
* @return the highest offset or position allowed for this buffer.
*/
@ForceInline
default long readLimit() {
return realCapacity();
}
@ForceInline
default long writeLimit() {
return realCapacity();
}
/**
* Obtain the underlying addressForRead. This is for expert users only.
*
* @param offset within this buffer. addressForRead(start()) is the actual addressForRead of the first byte.
* @return the underlying addressForRead of the buffer
* @throws UnsupportedOperationException if the underlying buffer is on the heap
* @throws BufferUnderflowException if the offset is before the start() or the after the capacity()
*/
long addressForRead(long offset)
throws UnsupportedOperationException, BufferUnderflowException;
default long addressForRead(long offset, int buffer)
throws UnsupportedOperationException, BufferUnderflowException {
return addressForRead(offset);
}
/**
* Obtain the underlying addressForRead. This is for expert users only.
*
* @param offset within this buffer. addressForRead(start()) is the actual addressForRead of the first byte.
* @return the underlying addressForRead of the buffer
* @throws UnsupportedOperationException if the underlying buffer is on the heap
* @throws BufferOverflowException if the offset is before the start() or the after the capacity()
*/
long addressForWrite(long offset)
throws UnsupportedOperationException, BufferOverflowException;
long addressForWritePosition()
throws UnsupportedOperationException, BufferOverflowException;
default ByteOrder byteOrder() {
return ByteOrder.nativeOrder();
}
/**
* @return the streaming bytes for reading.
*/
@SuppressWarnings("rawtypes")
Bytes bytesForRead() throws IllegalStateException;
/**
* @return the streaming bytes for writing.
*/
@SuppressWarnings("rawtypes")
Bytes bytesForWrite() throws IllegalStateException;
/**
* Perform a 32-bit CAS at a given offset.
*
* @param offset to perform CAS
* @param expected value
* @param value to set
* @return true, if successful.
*/
boolean compareAndSwapInt(long offset, int expected, int value)
throws BufferOverflowException;
void testAndSetInt(long offset, int expected, int value);
/**
* Perform a 64-bit CAS at a given offset.
*
* @param offset to perform CAS
* @param expected value
* @param value to set
* @return true, if successful.
*/
boolean compareAndSwapLong(long offset, long expected, long value)
throws BufferOverflowException;
/**
* Perform a 32-bit float CAS at a given offset.
*
* @param offset to perform CAS
* @param expected value
* @param value to set
* @return true, if successful.
*/
default boolean compareAndSwapFloat(long offset, float expected, float value)
throws BufferOverflowException {
return compareAndSwapInt(offset, Float.floatToRawIntBits(expected), Float.floatToRawIntBits(value));
}
/**
* Perform a 64-bit double CAS at a given offset.
*
* @param offset to perform CAS
* @param expected value
* @param value to set
* @return true, if successful.
*/
default boolean compareAndSwapDouble(long offset, double expected, double value)
throws BufferOverflowException {
return compareAndSwapLong(offset, Double.doubleToRawLongBits(expected), Double.doubleToRawLongBits(value));
}
/**
* @return true if these Bytes use shared memory.
*/
boolean sharedMemory();
boolean isDirectMemory();
}

@ -1,578 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* This allows random access to the underling bytes. This instance can be used across threads as it is stateless.
* The thread safety of the underlying data depends on how the methods are used.
*/
public interface RandomDataInput extends RandomCommon {
String[] charToString = createCharToString();
static String[] createCharToString() {
String[] charToString = new String[256];
charToString[0] = "\u0660";
for (int i = 1; i < 21; i++)
charToString[i] = Character.toString((char) (i + 0x2487));
for (int i = ' '; i < 256; i++)
charToString[i] = Character.toString((char) i);
for (int i = 21; i < ' '; i++)
charToString[i] = "\\u00" + Integer.toHexString(i).toUpperCase();
for (int i = 0x80; i < 0xA0; i++)
charToString[i] = "\\u00" + Integer.toHexString(i).toUpperCase();
return charToString;
}
default int peekVolatileInt() throws BufferUnderflowException {
return readVolatileInt(readPosition());
}
/**
* Read boolean at an offset
*
* @param offset to read
* @return the boolean
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
@ForceInline
default boolean readBoolean(long offset)
throws BufferUnderflowException {
return BytesUtil.byteToBoolean(readByte(offset));
}
/**
* Read byte at an offset
*
* @param offset to read
* @return the byte
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
byte readByte(long offset) throws BufferUnderflowException;
/**
* Read an unsigned byte at an offset
*
* @param offset to read
* @return the unsigned byte
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
@ForceInline
default int readUnsignedByte(long offset) throws BufferUnderflowException {
return readByte(offset) & 0xFF;
}
/**
* Read an unsigned byte at an offset, or -1
*
* @param offset to read
* @return the unsigned byte or -1
*/
int peekUnsignedByte(long offset) throws BufferUnderflowException;
/**
* Read a short at an offset
*
* @param offset to read
* @return the short
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
short readShort(long offset) throws BufferUnderflowException;
/**
* Read an unsigned short at an offset
*
* @param offset to read
* @return the unsigned short
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
@ForceInline
default int readUnsignedShort(long offset) throws BufferUnderflowException {
return readShort(offset) & 0xFFFF;
}
/**
* Read an unsigned int at an offset
*
* @param offset to read
* @return the int
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default int readUnsignedInt24(long offset) throws BufferUnderflowException {
return readUnsignedShort(offset) | (readUnsignedByte(offset) << 16);
}
/**
* Read an int at an offset
*
* @param offset to read
* @return the int
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
int readInt(long offset) throws BufferUnderflowException;
/**
* Read an unsigned int at an offset
*
* @param offset to read
* @return the unsigned int
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
@ForceInline
default long readUnsignedInt(long offset) throws BufferUnderflowException {
return readInt(offset) & 0xFFFFFFFFL;
}
/**
* Read a long at an offset
*
* @param offset to read
* @return the long
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
long readLong(long offset) throws BufferUnderflowException;
/**
* Read a float at an offset
*
* @param offset to read
* @return the float
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
float readFloat(long offset) throws BufferUnderflowException;
/**
* Read a double at an offset
*
* @param offset to read
* @return the double
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
double readDouble(long offset) throws BufferUnderflowException;
/**
* Read the byte at an offset and converts it into a printable
*
* @param offset to read
* @return the byte in a printable form.
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default String printable(long offset) throws BufferUnderflowException {
return charToString[readUnsignedByte(offset)];
}
/**
* Read a 8-bit byte from memory with a load barrier.
*
* @param offset to read
* @return the byte value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
byte readVolatileByte(long offset) throws BufferUnderflowException;
/**
* Read a 16-bit short from memory with a load barrier.
*
* @param offset to read
* @return the short value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
short readVolatileShort(long offset) throws BufferUnderflowException;
/**
* Read a 32-bit int from memory with a load barrier.
*
* @param offset to read
* @return the int value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
int readVolatileInt(long offset) throws BufferUnderflowException;
/**
* Read a float from memory with a load barrier.
*
* @param offset to read
* @return the float value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default float readVolatileFloat(long offset) throws BufferUnderflowException {
return Float.intBitsToFloat(readVolatileInt(offset));
}
/**
* Read a 64-bit long from memory with a load barrier.
*
* @param offset to read
* @return the long value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
long readVolatileLong(long offset) throws BufferUnderflowException;
/**
* Read a 64-bit double from memory with a load barrier.
*
* @param offset to read
* @return the double value
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default double readVolatileDouble(long offset) throws BufferUnderflowException {
return Double.longBitsToDouble(readVolatileLong(offset));
}
default long parseLong(long offset) throws BufferUnderflowException {
return BytesInternal.parseLong(this, offset);
}
/**
* expert level method for copying data to native memory.
*
* @param position within the ByteStore to copy.
* @param address in native memory
* @param size in bytes
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
void nativeRead(long position, long address, long size) throws BufferUnderflowException;
/**
* Read a byte[] from memory.
*
* @return the length actually read.
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default int copyTo( byte[] bytes) throws BufferUnderflowException {
int len = (int) Math.min(bytes.length, readRemaining());
for (int i = 0; i < len; i++)
bytes[i] = readByte(start() + i);
return len;
}
/**
* Copy data from this RandomDataInput to the ByteBuffer. The minimum of {@link #readRemaining()} and
* {@link ByteBuffer#remaining()}. Starting from {@link #start()} in this RandomDataInput and from {@link
* ByteBuffer#position()} of the given bb. Does NOT change the position or limit or mark of the given ByteBuffer.
* Returns the number of the copied bytes.
*/
default int copyTo( ByteBuffer bb) throws BufferUnderflowException {
int pos = bb.position();
int len = (int) Math.min(bb.remaining(), readRemaining());
int i;
for (i = 0; i < len - 7; i += 8)
bb.putLong(pos + i, readLong(start() + i));
for (; i < len; i++)
bb.put(pos + i, readByte(start() + i));
return len;
}
/**
* Read a long which is zero padded (high bytes) if the available bytes is less than 8.
* If the offset is at or beyond the readLimit, this will return 0L.
*
* @param offset to read from
* @return the long which might be padded.
*/
default long readIncompleteLong(long offset) {
long left = readLimit() - offset;
long l;
try {
if (left >= 8)
return readLong(offset);
if (left == 4)
return readInt(offset);
l = 0;
for (int i = 0, remaining = (int) left; i < remaining; i++) {
l |= (long) readUnsignedByte(offset + i) << (i * 8);
}
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
return l;
}
/**
* Returns the actual capacity that can be potentially read.
*
* @return the actual capacity that can be potentially read.
*/
long realCapacity();
/**
* Perform an atomic add and get operation for a 32-bit int
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default int addAndGetInt(long offset, int adding)
throws BufferUnderflowException {
return BytesInternal.addAndGetInt(this, offset, adding);
}
/**
* Perform an atomic add and get operation for a 64-bit long
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default long addAndGetLong(long offset, long adding)
throws BufferUnderflowException {
return BytesInternal.addAndGetLong(this, offset, adding);
}
/**
* Perform an atomic add and get operation for a 32-bit float
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default float addAndGetFloat(long offset, float adding)
throws BufferUnderflowException {
return BytesInternal.addAndGetFloat(this, offset, adding);
}
/**
* Perform an atomic add and get operation for a 64-bit double
*
* @param offset to add and get
* @param adding value to add, can be 1
* @return the sum
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
default double addAndGetDouble(long offset, double adding)
throws BufferUnderflowException {
return BytesInternal.addAndGetDouble(this, offset, adding);
}
/**
* Copy a sub sequence of bytes as a BytesStore.
*
* @param start of bytes
* @param length of bytes
* @return ByteStore copy.
*/
@SuppressWarnings("rawtypes")
default BytesStore subBytes(long start, long length) throws BufferUnderflowException {
return BytesInternal.subBytes(this, start, length);
}
default long findByte(byte stopByte) {
return BytesInternal.findByte(this, stopByte);
}
/**
* Truncates {@code sb} (it must be a {@link StringBuilder} or {@link Bytes}) and reads a char
* sequence from the given {@code offset}, encoded as Utf8, into it. Returns offset <i>after</i>
* the read Utf8, if a normal char sequence was read, or {@code -1 - offset}, if {@code null}
* was observed (in this case, {@code sb} is truncated too, but not updated then, by querying
* {@code sb} only this case is indistinguishable from reading an empty char sequence).
*
* @param offset the offset in this {@code RandomDataInput} to read char sequence from
* @param sb the buffer to read char sequence into (truncated first)
* @param <ACS> buffer type, must be {@code StringBuilder} or {@code Bytes}
* @return offset after the normal read char sequence, or -1 - offset, if char sequence is
* {@code null}
* @see RandomDataOutput#writeUtf8(long, CharSequence)
*/
default <ACS extends Appendable & CharSequence> long readUtf8(long offset, ACS sb)
throws IORuntimeException, IllegalArgumentException, BufferUnderflowException {
AppendableUtil.setLength(sb, 0);
// TODO insert some bounds check here
long utfLen;
if ((utfLen = readByte(offset++)) < 0) {
utfLen &= 0x7FL;
long b;
int count = 7;
while ((b = readByte(offset++)) < 0) {
utfLen |= (b & 0x7FL) << count;
count += 7;
}
if (b != 0) {
if (count > 56)
throw new IORuntimeException(
"Cannot read more than 9 stop bits of positive value");
utfLen |= (b << count);
} else {
if (count > 63)
throw new IORuntimeException(
"Cannot read more than 10 stop bits of negative value");
utfLen = ~utfLen;
}
}
if (utfLen == -1)
return ~offset;
int len = Maths.toUInt31(utfLen);
BytesInternal.parseUtf8(this, offset, sb, true, len);
return offset + utfLen;
}
/**
* Truncates {@code sb} (it must be a {@link StringBuilder} or {@link Bytes}) and reads a char
* sequence from the given {@code offset}, encoded as Utf8, into it. Returns offset <i>after</i>
* the read Utf8, if a normal char sequence was read, or {@code -1 - offset}, if {@code null}
* was observed (in this case, {@code sb} is truncated too, but not updated then, by querying
* {@code sb} only this case is indistinguishable from reading an empty char sequence). If
* length of Utf8 encoding of the char sequence exceeds {@code maxUtf8Len},
* {@code IllegalStateException} is thrown.
*
* @param offset the offset in this {@code RandomDataInput} to read char sequence from
* @param sb the buffer to read char sequence into (truncated first)
* @param maxUtf8Len the maximum allowed length of the char sequence in Utf8 encoding
* @param <ACS> buffer type, must be {@code StringBuilder} or {@code Bytes}
* @return offset after the normal read char sequence, or -1 - offset, if char sequence is
* {@code null}
* @see RandomDataOutput#writeUtf8Limited(long, CharSequence, int)
*/
default <ACS extends Appendable & CharSequence> long readUtf8Limited(
long offset, ACS sb, int maxUtf8Len)
throws IORuntimeException, IllegalArgumentException, BufferUnderflowException,
IllegalStateException {
AppendableUtil.setLength(sb, 0);
// TODO insert some bounds check here
long utfLen;
if ((utfLen = readByte(offset++)) < 0) {
utfLen &= 0x7FL;
long b;
int count = 7;
while ((b = readByte(offset++)) < 0) {
utfLen |= (b & 0x7FL) << count;
count += 7;
}
if (b != 0) {
if (count > 56)
throw new IORuntimeException(
"Cannot read more than 9 stop bits of positive value");
utfLen |= (b << count);
} else {
if (count > 63)
throw new IORuntimeException(
"Cannot read more than 10 stop bits of negative value");
utfLen = ~utfLen;
}
}
if (utfLen == -1)
return ~offset;
if (utfLen > maxUtf8Len)
throw new IllegalStateException("Attempted to read a char sequence of " +
"utf8 size " + utfLen + ", when only " + maxUtf8Len + " allowed");
BytesInternal.parseUtf8(this, offset, sb, true, (int) utfLen);
return offset + utfLen;
}
/**
* Reads a char sequence from the given {@code offset}, encoded as Utf8. If length of Utf8
* encoding of the char sequence exceeds {@code maxUtf8Len}, {@code IllegalStateException}
* is thrown.
*
* @param offset the offset in this {@code RandomDataInput} to read char sequence from
* @param maxUtf8Len the maximum allowed length of the char sequence in Utf8 encoding
* @return the char sequence was read
* @see RandomDataOutput#writeUtf8Limited(long, CharSequence, int)
*/
default String readUtf8Limited(long offset, int maxUtf8Len)
throws BufferUnderflowException, IORuntimeException, IllegalArgumentException,
IllegalStateException {
return BytesInternal.readUtf8(this, offset, maxUtf8Len);
}
/**
* Compares the UTF-8 encoded char sequence, written in this {@code RandomDataInput} at the
* given offset, with the given char sequence. Returns {@code true}, if they are equal. Both
* char sequences (encoded in bytes and the given) may be {@code null}.
*
* @param offset the offset in this {@code RandomDataInput} where the char sequence to compare
* is written
* @param other the second char sequence to compare
* @return {@code true} if two char sequences are equal
* @throws IORuntimeException if the contents are not a valid string.
*/
default boolean compareUtf8(long offset, CharSequence other) throws IORuntimeException {
return BytesInternal.compareUtf8(this, offset, other);
}
default byte[] toByteArray() throws IllegalArgumentException {
return BytesInternal.toByteArray(this);
}
default long read(long offsetInRDI, byte[] bytes, int offset, int length) {
try {
int len = (int) Math.min(length, readLimit() - offsetInRDI);
for (int i = 0; i < len; i++)
bytes[offset + i] = readByte(offsetInRDI + i);
return len;
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
default ByteBuffer toTemporaryDirectByteBuffer() throws IllegalArgumentException {
int len = Maths.toUInt31(readRemaining());
try {
ByteBuffer bb = ByteBuffer.allocateDirect(len);
copyTo(bb);
bb.clear();
return bb;
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
default int fastHash(long offset, int length) throws BufferUnderflowException {
long hash = 0;
int i = 0;
if (length >= 4) {
hash = readInt(offset + i);
i += 4;
}
for (; i < length - 3; i += 4) {
hash *= 0x6d0f27bd;
hash += readInt(offset + i);
}
if (i < length - 1) {
hash *= 0x6d0f27bdL;
hash += readShort(offset + i);
i += 2;
}
if (i < length)
hash += readByte(offset + i);
hash *= 0x855dd4db;
return (int) (hash ^ (hash >> 32));
}
default boolean canReadDirect(long length) {
return isDirectMemory() && readRemaining() >= length;
}
}

@ -1,351 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@SuppressWarnings({"rawtypes", "unchecked"})
public interface RandomDataOutput<R extends RandomDataOutput<R>> extends RandomCommon {
/**
* Write a byte at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
* @throws IllegalArgumentException if the value cannot be cast to the type without loss.
*/
default R writeByte(long offset, int i)
throws BufferOverflowException, IllegalArgumentException {
return writeByte(offset, Maths.toInt8(i));
}
/**
* Write an unsigned byte at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
* @throws IllegalArgumentException if the value cannot be cast to the type without loss.
*/
default R writeUnsignedByte(long offset, int i)
throws BufferOverflowException, IllegalArgumentException {
return writeByte(offset, (byte) Maths.toUInt8(i));
}
/**
* Write a boolean at an offset.
*
* @param offset to write to
* @param flag the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
default R writeBoolean(long offset, boolean flag)
throws BufferOverflowException {
try {
return writeByte(offset, flag ? 'Y' : 'N');
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
}
/**
* Write an unsigned byte at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
* @throws IllegalArgumentException if the value cannot be cast to the type without loss.
*/
default R writeUnsignedShort(long offset, int i)
throws BufferOverflowException, IllegalArgumentException {
return writeShort(offset, (short) Maths.toUInt16(i));
}
/**
* Write an unsigned byte at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
* @throws IllegalArgumentException if the value cannot be cast to the type without loss.
*/
default R writeUnsignedInt(long offset, long i)
throws BufferOverflowException, IllegalArgumentException {
return writeInt(offset, (int) Maths.toUInt32(i));
}
/**
* Write an unsigned byte at an offset.
*
* @param offset to write to
* @param i8 the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeByte(long offset, byte i8) throws BufferOverflowException;
/**
* Write a short at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeShort(long offset, short i) throws BufferOverflowException;
default R writeInt24(long offset, int i) throws BufferOverflowException {
writeShort(offset, (short) i);
return writeByte(offset + 2, (byte) (i >> 16));
}
/**
* Write an int at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeInt(long offset, int i) throws BufferOverflowException;
/**
* Perform a non stalling write with a store barrier.
*
* @param offset to write to
* @param i value to write
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeOrderedInt(long offset, int i) throws BufferOverflowException;
/**
* Perform a non stalling write with a store barrier.
*
* @param offset to write to
* @param f value to write
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
default R writeOrderedFloat(long offset, float f) throws BufferOverflowException {
return writeOrderedInt(offset, Float.floatToRawIntBits(f));
}
/**
* Write a long at an offset.
*
* @param offset to write to
* @param i the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeLong(long offset, long i) throws BufferOverflowException, IllegalStateException;
/**
* Perform a non stalling write with a store barrier.
*
* @param offset to write to
* @param i value to write
* @return this
*/
R writeOrderedLong(long offset, long i) throws BufferOverflowException;
/**
* Perform a non stalling write with a store barrier.
*
* @param offset to write to
* @param d value to write
* @return this
*/
default R writeOrderedDouble(long offset, double d) throws BufferOverflowException {
return writeOrderedLong(offset, Double.doubleToRawLongBits(d));
}
/**
* Write a float at an offset.
*
* @param offset to write to
* @param d the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeFloat(long offset, float d) throws BufferOverflowException;
/**
* Write a double at an offset.
*
* @param offset to write to
* @param d the value
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R writeDouble(long offset, double d) throws BufferOverflowException;
R writeVolatileByte(long offset, byte i8) throws BufferOverflowException;
R writeVolatileShort(long offset, short i16) throws BufferOverflowException;
R writeVolatileInt(long offset, int i32) throws BufferOverflowException;
R writeVolatileLong(long offset, long i64) throws BufferOverflowException;
default R writeVolatileFloat(long offset, float f) throws BufferOverflowException {
return writeVolatileInt(offset, Float.floatToRawIntBits(f));
}
default R writeVolatileDouble(long offset, double d) throws BufferOverflowException {
return writeVolatileLong(offset, Double.doubleToRawLongBits(d));
}
default R write(long offsetInRDO, byte[] bytes) throws BufferOverflowException {
return write(offsetInRDO, bytes, 0, bytes.length);
}
R write(long offsetInRDO, byte[] bytes, int offset, int length)
throws BufferOverflowException;
void write(long offsetInRDO, ByteBuffer bytes, int offset, int length)
throws BufferOverflowException;
default R write(long offsetInRDO, BytesStore bytes)
throws BufferOverflowException {
try {
return write(offsetInRDO, bytes, bytes.readPosition(), bytes.readRemaining());
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
R write(long writeOffset, RandomDataInput bytes, long readOffset, long length)
throws BufferOverflowException, BufferUnderflowException;
/**
* Zero out the bytes between the start and the end.
*
* @param start index of first byte inclusive
* @param end index of last byte exclusive
* @return this
* @throws BufferOverflowException if the capacity was exceeded
*/
R zeroOut(long start, long end);
default R append(long offset, long value, int digits)
throws BufferOverflowException {
BytesInternal.append(this, offset, value, digits);
return (R) this;
}
default R append(long offset, double value, int decimalPlaces, int digits) throws BufferOverflowException {
if (decimalPlaces < 20) {
double d2 = value * Maths.tens(decimalPlaces);
if (d2 <= Long.MAX_VALUE && d2 >= Long.MIN_VALUE) {
BytesInternal.appendDecimal(this, Math.round(d2), offset, decimalPlaces, digits);
return (R) this;
}
}
BytesInternal.append((StreamingDataOutput) this, value);
return (R) this;
}
/**
* expert level method to copy data from native memory into the BytesStore
*
* @param address in native memory to copy from
* @param position in BytesStore to copy to
* @param size in bytes
*/
void nativeWrite(long address, long position, long size) throws BufferOverflowException;
/**
* Writes the given {@code cs} to this {@code RandomDataOutput} from the given {@code offset},
* in Utf8 format. Returns the offset after the written char sequence.
*
* @param offset the offset to write char sequence from
* @param cs the char sequence to write, could be {@code null}
* @return the offset after the char sequence written, in this {@code RandomDataOutput}
* @see RandomDataInput#readUtf8(long, Appendable)
*/
default long writeUtf8(long offset, CharSequence cs) throws BufferOverflowException {
return BytesInternal.writeUtf8(this, offset, cs);
}
/**
* Writes the given {@code cs} to this {@code RandomDataOutput} from the given {@code offset},
* in Utf8 format, checking that the utf8 encoding size of the given char sequence is less or
* equal to the given {@code maxUtf8Len}, otherwise {@code IllegalArgumentException} is thrown,
* and no bytes of this {@code RandomDataOutput} are overwritten. Returns the offset after the
* written char sequence.
*
* @param offset the offset to write char sequence from
* @param cs the char sequence to write, could be {@code null}
* @param maxUtf8Len the maximum allowed length (in Utf8 encoding) of the given char sequence
* @return the offset after the char sequence written, in this {@code RandomDataOutput}
* @throws IllegalArgumentException if the given char sequence size in Utf8 encoding exceeds
* maxUtf8Len
* @see RandomDataInput#readUtf8Limited(long, Appendable, int)
* @see RandomDataInput#readUtf8Limited(long, int)
*/
default long writeUtf8Limited(long offset, CharSequence cs, int maxUtf8Len)
throws BufferOverflowException {
return BytesInternal.writeUtf8(this, offset, cs, maxUtf8Len);
}
}

@ -1,37 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.annotation.DontChain;
import net.openhft.chronicle.core.io.IORuntimeException;
/**
* Read data directly as Bytes.
*/
@FunctionalInterface
@DontChain
public interface ReadBytesMarshallable extends CommonMarshallable {
/**
* Bytes to read. This can be used as a method to implement or as a lambda.
*
* @param bytes to read.
*/
@SuppressWarnings("rawtypes")
void readMarshallable(BytesIn bytes) throws IORuntimeException;
}

@ -1,183 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.ReferenceOwner;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* BytesStore to wrap memory mapped data.
*/
public class ReadOnlyMappedBytesStore extends MappedBytesStore {
public ReadOnlyMappedBytesStore(ReferenceOwner owner, MappedFile mappedFile, long start, long address, long capacity, long safeCapacity)
throws IllegalStateException {
super(owner, mappedFile, start, address, capacity, safeCapacity);
}
@Override
public NativeBytesStore<Void> zeroOut(long start, long end) {
return this;
}
@Override
public boolean compareAndSwapInt(long offset, int expected, int value) {
throw checkReadOnly();
}
@Override
public boolean compareAndSwapLong(long offset, long expected, long value) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeByte(long offset, byte i8) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeShort(long offset, short i16) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeInt(long offset, int i32) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeLong(long offset, long i64) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeOrderedLong(long offset, long i) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeFloat(long offset, float f) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeDouble(long offset, double d) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeVolatileByte(long offset, byte i8) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeVolatileShort(long offset, short i16) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeVolatileInt(long offset, int i32) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeVolatileLong(long offset, long i64) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> write(long offsetInRDO, byte[] bytes, int offset, int length) {
throw checkReadOnly();
}
@Override
public void write(long offsetInRDO, ByteBuffer bytes, int offset, int length) {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> write(long writeOffset, RandomDataInput bytes, long readOffset, long length)
throws BufferOverflowException, BufferUnderflowException {
throw checkReadOnly();
}
@Override
public void write0(long offsetInRDO, RandomDataInput bytes, long offset, long length) {
throw checkReadOnly();
}
@Override
public void nativeWrite(long address, long position, long size) {
throw checkReadOnly();
}
@Override
void write8bit(long position, char[] chars, int offset, int length) {
throw checkReadOnly();
}
@Override
public long appendUTF(long pos, char[] chars, int offset, int length) {
throw checkReadOnly();
}
@Override
public long appendUtf8(long pos, char[] chars, int offset, int length) {
throw checkReadOnly();
}
@Override
public VanillaBytes<Void> bytesForWrite() throws IllegalStateException {
throw checkReadOnly();
}
@Override
public NativeBytesStore<Void> writeOrderedInt(long offset, int i) {
throw checkReadOnly();
}
private IllegalStateException checkReadOnly() throws IllegalStateException {
throw new IllegalStateException("Read Only");
}
@Override
public boolean readWrite() {
return false;
}
}

@ -1,319 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.ReferenceOwner;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* applied after a Bytes has been released and cannot be used.
*
* @see NoBytesStore
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public enum ReleasedBytesStore implements BytesStore {
RELEASED_BYTES_STORE;
public static <T, B extends BytesStore<B, T>> BytesStore<B, T> releasedBytesStore() {
return RELEASED_BYTES_STORE;
}
@Override
public void reserve(ReferenceOwner id) throws IllegalStateException {
throw newIllegalStateException();
}
@Override
public void release(ReferenceOwner id) throws IllegalStateException {
throw newIllegalStateException();
}
@Override
public int refCount() {
return 0;
}
@Override
public boolean tryReserve(ReferenceOwner id) throws IllegalStateException {
return false;
}
@Override
public boolean reservedBy(ReferenceOwner owner) {
return false;
}
@Override
public void releaseLast(ReferenceOwner id) throws IllegalStateException {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeByte(long offset, byte i8) {
throw newIllegalStateException();
}
private IllegalStateException newIllegalStateException() {
return new IllegalStateException("released");
}
@Override
public RandomDataOutput writeShort(long offset, short i) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeInt(long offset, int i) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeOrderedInt(long offset, int i) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeLong(long offset, long i) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeOrderedLong(long offset, long i) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeFloat(long offset, float d) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeDouble(long offset, double d) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeVolatileByte(long offset, byte i8) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeVolatileShort(long offset, short i16) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeVolatileInt(long offset, int i32) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput writeVolatileLong(long offset, long i64) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput write(long offsetInRDO, byte[] bytes, int offset, int length) {
if (length != 0)
throw newIllegalStateException();
return this;
}
@Override
public void write(long offsetInRDO, ByteBuffer bytes, int offset, int length) {
throw newIllegalStateException();
}
@Override
public RandomDataOutput write(long writeOffset, RandomDataInput bytes, long readOffset, long length) {
throw newIllegalStateException();
}
@Override
public byte readByte(long offset) {
throw newIllegalStateException();
}
@Override
public int peekUnsignedByte(long offset) {
return -1;
}
@Override
public short readShort(long offset) {
throw newIllegalStateException();
}
@Override
public int readInt(long offset) {
throw newIllegalStateException();
}
@Override
public long readLong(long offset) {
throw newIllegalStateException();
}
@Override
public float readFloat(long offset) {
throw newIllegalStateException();
}
@Override
public double readDouble(long offset) {
throw newIllegalStateException();
}
@Override
public byte readVolatileByte(long offset) throws BufferUnderflowException {
throw newIllegalStateException();
}
@Override
public short readVolatileShort(long offset) throws BufferUnderflowException {
throw newIllegalStateException();
}
@Override
public int readVolatileInt(long offset) throws BufferUnderflowException {
throw newIllegalStateException();
}
@Override
public long readVolatileLong(long offset) throws BufferUnderflowException {
throw newIllegalStateException();
}
@Override
public boolean isDirectMemory() {
return false;
}
@Override
public BytesStore copy() {
return this;
}
@Override
public long capacity() {
return 0;
}
@Override
public Void underlyingObject() {
return null;
}
@Override
public boolean inside(long offset) {
return false;
}
@Override
public boolean inside(long offset, long buffer) {
return false;
}
@Override
public long copyTo( BytesStore store) {
throw newIllegalStateException();
}
@Override
public void nativeWrite(long address, long position, long size) {
throw newIllegalStateException();
}
@Override
public void nativeRead(long position, long address, long size) {
throw newIllegalStateException();
}
@Override
public boolean compareAndSwapInt(long offset, int expected, int value) {
throw newIllegalStateException();
}
@Override
public void testAndSetInt(long offset, int expected, int value) {
throw newIllegalStateException();
}
@Override
public boolean compareAndSwapLong(long offset, long expected, long value) {
throw newIllegalStateException();
}
@Override
public boolean equalBytes( BytesStore bytesStore, long length) {
throw newIllegalStateException();
}
@Override
public void move(long from, long to, long length) {
throw newIllegalStateException();
}
@Override
public long addressForRead(long offset) throws BufferUnderflowException {
throw newIllegalStateException();
}
@Override
public long addressForWrite(long offset) throws BufferOverflowException {
throw newIllegalStateException();
}
@Override
public long addressForWritePosition() throws UnsupportedOperationException, BufferOverflowException {
throw newIllegalStateException();
}
@Override
public Bytes bytesForWrite() {
throw newIllegalStateException();
}
@Override
public boolean sharedMemory() {
return false;
}
}

@ -1,69 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.Closeable;
public interface RingBufferReader extends RingBufferReaderStats, Closeable {
long UNKNOWN_INDEX = -1;
boolean isEmpty();
boolean isStopped();
/**
* stop the reader. After being stopped, the reader will not block writers.
* After being stopped the reader can be re-opened
*/
void stop();
/**
* the readPosition and readLimit will be adjusted so that the client can read the data
*
* @param bytes who's byteStore must be the ring buffer,
* @return nextReadPosition which should be passed to {@link RingBufferReader#afterRead(long)}
*/
@SuppressWarnings("rawtypes")
long beforeRead(Bytes bytes);
void afterRead(long next);
void afterRead(long next, long payloadStart, long underlyingIndex);
long underlyingIndex();
/**
* Convenience method calls both {@link #beforeRead(Bytes)} and {@link #afterRead(long)}
*
* @param bytes
* @return whether read succeeded
*/
@SuppressWarnings("rawtypes")
boolean read(BytesOut bytes);
/**
* @return the byteStore which backs the ring buffer
*/
@SuppressWarnings("rawtypes")
BytesStore byteStore();
/**
* Take reader to just past the end of the RB
*/
void toEnd();
}

@ -1,27 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
public interface RingBufferReaderStats {
long getAndClearReadCount();
long getAndClearMissedReadCount();
long behind();
}

@ -1,42 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.util.EscapingStopCharTester;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface StopCharTester {
/**
* Detect which byte stops the string to be parsed
* <p>
* <p>This should be changed to support char instead.
* <p>
* <p>Note: for safety reasons, you should stop on a 0 byte or throw an IllegalStateException.
*
* @param ch to test, 0 should return true or throw an exception.
* @return if this byte is a stop character.
*/
boolean isStopChar(int ch);
default StopCharTester escaping() {
return new EscapingStopCharTester(this);
}
}

@ -1,107 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
public enum StopCharTesters implements StopCharTester {
COMMA_STOP {
@Override
public boolean isStopChar(int ch) {
return ch < ' ' || ch == ',';
}
},
CURLY_STOP {
@Override
public boolean isStopChar(int ch) {
return ch < ' ' || ch == '}';
}
},
COMMA_SPACE_STOP {
@Override
public boolean isStopChar(int ch) {
return ch <= ' ' || ch == ',';
}
},
CONTROL_STOP {
@Override
public boolean isStopChar(int ch) {
return ch < ' ';
}
},
SPACE_STOP {
@Override
public boolean isStopChar(int ch) {
return Character.isWhitespace(ch) || ch == 0;
}
},
QUOTES {
@Override
public boolean isStopChar(int ch) {
return ch == '"' || ch <= 0;
}
},
SINGLE_QUOTES {
@Override
public boolean isStopChar(int ch) {
return ch == '\'' || ch <= 0;
}
},
EQUALS {
@Override
public boolean isStopChar(int ch) {
return ch == '=' || ch <= 0;
}
},
NUMBER_END {
@Override
public boolean isStopChar(int ch) {
switch (ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
case '.':
case 'E':
case 'e':
return false;
default:
return true;
}
}
},
NON_ALPHA_DIGIT {
@Override
public boolean isStopChar(int ch) {
return ch < '0' || !(Character.isAlphabetic(ch) || Character.isDigit(ch));
}
},
ALL {
@Override
public boolean isStopChar(int ch) {
return ch < 0;
}
}
}

@ -1,43 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.util.EscapingStopCharsTester;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface StopCharsTester {
/**
* Detect which byte or bytes stops the string to be parsed
* <p>
* <p>This should be changed to support char instead.
* <p>
* <p>Note: for safety reasons, you should stop on a 0 byte or throw an IllegalStateException.
*
* @param ch to test, 0 should return true or throw an exception.
* @param ch2 to test, 0 should return true or throw an exception.
* @return if this byte is a stop character.
*/
boolean isStopChar(int ch, int ch2);
default StopCharsTester escaping() {
return new EscapingStopCharsTester(this);
}
}

@ -1,32 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
public interface StreamingCommon<S extends StreamingCommon<S>> extends RandomCommon {
/**
* Set the readPosition= writePosition = start, writeLimit = capacity
*
* @return this
*/
S clear();
}

@ -1,438 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.UnsafeMemory;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.util.Histogram;
import net.openhft.chronicle.core.util.ThrowingConsumer;
import net.openhft.chronicle.core.util.ThrowingConsumerNonCapturing;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* This data input has a a position() and a limit()
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface StreamingDataInput<S extends StreamingDataInput<S>> extends StreamingCommon<S> {
S readPosition(long position) throws BufferUnderflowException;
default S readPositionUnlimited(long position) throws BufferUnderflowException {
return readLimitToCapacity().readPosition(position);
}
default S readPositionRemaining(long position, long remaining) throws BufferUnderflowException {
readLimit(position + remaining);
return readPosition(position);
}
S readLimit(long limit) throws BufferUnderflowException;
default S readLimitToCapacity() throws BufferUnderflowException {
return readLimit(capacity());
}
/**
* Skip a number of bytes by moving the readPosition. Must be less than or equal to the readLimit.
*
* @param bytesToSkip bytes to skip.
* @return this
* @throws BufferUnderflowException if the offset is outside the limits of the Bytes
*/
S readSkip(long bytesToSkip) throws BufferUnderflowException;
/**
* Read skip 1 when you are sure this is safe. Use at your own risk when you find a performance problem.
*/
void uncheckedReadSkipOne();
/**
* Read skip -1 when you are sure this is safe. Use at your own risk when you find a performance problem.
*/
void uncheckedReadSkipBackOne();
/**
* Perform a set of actions with a temporary bounds mode.
*/
default void readWithLength0(long length, ThrowingConsumerNonCapturing<S, IORuntimeException, BytesOut> bytesConsumer, StringBuilder sb, BytesOut toBytes)
throws BufferUnderflowException, IORuntimeException {
if (length > readRemaining())
throw new BufferUnderflowException();
long limit0 = readLimit();
long limit = readPosition() + length;
try {
readLimit(limit);
bytesConsumer.accept((S) this, sb, toBytes);
} finally {
readLimit(limit0);
readPosition(limit);
}
}
/**
* Perform a set of actions with a temporary bounds mode.
*/
default void readWithLength(long length, ThrowingConsumer<S, IORuntimeException> bytesConsumer)
throws BufferUnderflowException, IORuntimeException {
if (length > readRemaining())
throw new BufferUnderflowException();
long limit0 = readLimit();
long limit = readPosition() + length;
try {
readLimit(limit);
bytesConsumer.accept((S) this);
} finally {
readLimit(limit0);
readPosition(limit);
}
}
default InputStream inputStream() {
return new StreamingInputStream(this);
}
default long readStopBit() throws IORuntimeException {
return BytesInternal.readStopBit(this);
}
default char readStopBitChar() throws IORuntimeException {
return BytesInternal.readStopBitChar(this);
}
default double readStopBitDouble() {
return BytesInternal.readStopBitDouble(this);
}
default double readStopBitDecimal() throws BufferOverflowException {
long value = readStopBit();
int scale = (int) (Math.abs(value) % 10);
value /= 10;
return (double) value / Maths.tens(scale);
}
default boolean readBoolean() {
byte b = readByte();
return BytesUtil.byteToBoolean(b);
}
byte readByte();
default byte rawReadByte() {
return readByte();
}
default char readChar() {
return readStopBitChar();
}
/**
* @return the next unsigned 8 bit value or -1;
*/
int readUnsignedByte();
/**
* @return the next unsigned 8 bit value or -1;
*/
int uncheckedReadUnsignedByte();
short readShort() throws BufferUnderflowException;
default int readUnsignedShort() throws BufferUnderflowException {
return readShort() & 0xFFFF;
}
default int readInt24() throws BufferUnderflowException {
return readUnsignedShort() | (readUnsignedByte() << 24 >> 8);
}
default int readUnsignedInt24() throws BufferUnderflowException {
return readUnsignedShort() | (readUnsignedByte() << 16);
}
int readInt() throws BufferUnderflowException;
default int rawReadInt() {
return readInt();
}
default long readUnsignedInt()
throws BufferUnderflowException {
return readInt() & 0xFFFFFFFFL;
}
long readLong() throws BufferUnderflowException;
default long rawReadLong() {
return readLong();
}
/**
* @return a long using the bytes remaining
*/
default long readIncompleteLong() {
long left = readRemaining();
try {
if (left >= 8)
return readLong();
if (left == 4)
return readInt();
long l = 0;
for (int i = 0, remaining = (int) left; i < remaining; i++) {
l |= (long) readUnsignedByte() << (i * 8);
}
return l;
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
float readFloat() throws BufferUnderflowException;
double readDouble() throws BufferUnderflowException;
/**
* The same as readUTF() except the length is stop bit encoded. This saves one byte for strings shorter than 128
* chars. <code>null</code> values are also supported
*
* @return a Unicode string or <code>null</code> if <code>writeUtf8(null)</code> was called
*/
default String readUtf8()
throws BufferUnderflowException, IORuntimeException, IllegalArgumentException {
return BytesInternal.readUtf8(this);
}
@Deprecated(/* to be removed in x.22 */)
default String readUTFΔ()
throws IORuntimeException, BufferUnderflowException, IllegalArgumentException {
return BytesInternal.readUtf8(this);
}
default String read8bit() throws IORuntimeException, BufferUnderflowException {
return BytesInternal.read8bit(this);
}
/**
* The same as readUtf8() except the chars are copied to a truncated StringBuilder.
*
* @param sb to copy chars to
* @return <code>true</code> if there was a String, or <code>false</code> if it was <code>null</code>
*/
default <ACS extends Appendable & CharSequence> boolean readUtf8( ACS sb)
throws IORuntimeException, IllegalArgumentException, BufferUnderflowException {
AppendableUtil.setLength(sb, 0);
if (readRemaining() <= 0)
// TODO throw BufferUnderflowException here? please review
return false;
long len0 = readStopBit();
if (len0 == -1)
return false;
int len = Maths.toUInt31(len0);
if (len > 0)
BytesInternal.parseUtf8(this, sb, true, len);
return true;
}
@Deprecated(/* to be removed in x.22 */)
default <ACS extends Appendable & CharSequence> boolean readUTFΔ( ACS sb)
throws IORuntimeException, IllegalArgumentException, BufferUnderflowException {
return readUtf8(sb);
}
default boolean read8bit( Bytes b)
throws BufferUnderflowException, IllegalStateException, BufferOverflowException {
b.clear();
if (readRemaining() <= 0)
return false;
long len0 = this.readStopBit();
if (len0 == -1)
return false;
int len = Maths.toUInt31(len0);
b.write((BytesStore) this, readPosition(), len);
readSkip(len);
return true;
}
default <ACS extends Appendable & CharSequence> boolean read8bit( ACS sb)
throws IORuntimeException, IllegalArgumentException, BufferUnderflowException {
AppendableUtil.setLength(sb, 0);
long len0 = BytesInternal.readStopBit(this);
if (len0 == -1)
return false;
int len = Maths.toUInt31(len0);
try {
AppendableUtil.parse8bit(this, sb, len);
} catch (IOException e) {
throw new IORuntimeException(e);
}
return true;
}
default boolean read8bit( StringBuilder sb)
throws IORuntimeException, BufferUnderflowException {
sb.setLength(0);
long len0 = BytesInternal.readStopBit(this);
if (len0 == -1)
return false;
int len = Maths.toUInt31(len0);
try {
AppendableUtil.parse8bit(this, sb, len);
} catch (IOException e) {
throw new IORuntimeException(e);
}
return true;
}
default int read( byte[] bytes) {
return read(bytes, 0, bytes.length);
}
default int read( byte[] bytes, int off, int len) {
long remaining = readRemaining();
if (remaining <= 0)
return -1;
int len2 = (int) Math.min(len, remaining);
int i = 0;
for (; i < len2 - 7; i += 8)
UnsafeMemory.unsafePutLong(bytes, i + off, rawReadLong());
for (; i < len2; i++)
bytes[off + i] = rawReadByte();
return len2;
}
default int read( char[] bytes, int off, int len) {
long remaining = readRemaining();
if (remaining <= 0)
return -1;
int len2 = (int) Math.min(len, remaining);
for (int i = 0; i < len2; i++)
bytes[off + i] = (char) readUnsignedByte();
return len2;
}
default void read( ByteBuffer buffer) {
for (int i = (int) Math.min(readRemaining(), buffer.remaining()); i > 0; i--)
buffer.put(readByte());
}
default void read( Bytes bytes, int length) {
int len2 = (int) Math.min(length, readRemaining());
int i = 0;
for (; i < len2 - 7; i += 8)
bytes.rawWriteLong(rawReadLong());
for (; i < len2; i++)
bytes.rawWriteByte(rawReadByte());
}
default void unsafeReadObject(Object o, int length) {
unsafeReadObject(o, (o.getClass().isArray() ? 4 : 0) + Jvm.objectHeaderSize(), length);
}
default void unsafeReadObject(Object o, int offset, int length) {
assert BytesUtil.isTriviallyCopyable(o.getClass(), offset, length);
if (readRemaining() < length)
throw new BufferUnderflowException();
int i = 0;
for (; i < length - 7; i += 8)
UnsafeMemory.unsafePutLong(o, offset + i, rawReadLong());
for (; i < length; i++)
UnsafeMemory.unsafePutByte(o, offset + i, rawReadByte());
}
int readVolatileInt() throws BufferUnderflowException;
long readVolatileLong() throws BufferUnderflowException;
int peekUnsignedByte();
default <E extends Enum<E>> E readEnum( Class<E> eClass)
throws IORuntimeException, BufferUnderflowException {
return BytesInternal.readEnum(this, eClass);
}
@Deprecated(/* to be removed in x.22 */)
default void parseUTF(Appendable sb, int length)
throws IllegalArgumentException, BufferUnderflowException, UTFDataFormatRuntimeException {
parseUtf8(sb, length);
}
default void parseUtf8(Appendable sb, int encodedLength)
throws IllegalArgumentException, BufferUnderflowException, UTFDataFormatRuntimeException {
parseUtf8(sb, true, encodedLength);
}
default void parseUtf8(Appendable sb, boolean utf, int length)
throws IllegalArgumentException, BufferUnderflowException, UTFDataFormatRuntimeException {
AppendableUtil.setLength(sb, 0);
BytesInternal.parseUtf8(this, sb, utf, length);
}
default long parseHexLong() {
return BytesInternal.parseHexLong(this);
}
void copyTo(OutputStream out) throws IOException;
long copyTo(BytesStore to);
default void readHistogram( Histogram histogram) {
BytesInternal.readHistogram(this, histogram);
}
default void readWithLength(Bytes bytes) {
bytes.clear();
int length = Maths.toUInt31(readStopBit());
int i;
for (i = 0; i < length - 7; i++)
bytes.writeLong(readLong());
for (; i < length; i++)
bytes.writeByte(readByte());
}
/**
* When there is no more data to read, return zero, false and empty string.
*
* @param lenient if true, return nothing rather than error.
*/
void lenient(boolean lenient);
boolean lenient();
}

@ -1,562 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.UnsafeMemory;
import net.openhft.chronicle.core.annotation.Java9;
import net.openhft.chronicle.core.util.Histogram;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* Position based access. Once data has been read, the position() moves.
* <p>The use of this instance is single threaded, though the use of the data
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface StreamingDataOutput<S extends StreamingDataOutput<S>> extends StreamingCommon<S> {
int JAVA9_STRING_CODER_LATIN = 0;
int JAVA9_STRING_CODER_UTF16 = 1;
S writePosition(long position) throws BufferOverflowException;
S writeLimit(long limit) throws BufferOverflowException;
/**
* Skip a number of bytes by moving the writePosition. Must be less than or equal to the writeLimit.
*
* @param bytesToSkip bytes to skip.
* @return this
* @throws BufferOverflowException if the offset is outside the limits of the Bytes
*/
S writeSkip(long bytesToSkip) throws BufferOverflowException;
default S alignBy(int width) {
return writeSkip((-writePosition()) & (width - 1));
}
/**
* @return Bytes as an OutputStream
*/
default OutputStream outputStream() {
return new StreamingOutputStream(this);
}
/**
* Write a stop bit encoded long
*
* @param x long to write
* @return this.
*/
default S writeStopBit(long x) throws BufferOverflowException {
BytesInternal.writeStopBit(this, x);
return (S) this;
}
default S writeStopBit(char x) throws BufferOverflowException {
BytesInternal.writeStopBit(this, x);
return (S) this;
}
default S writeStopBit(double d) throws BufferOverflowException {
BytesInternal.writeStopBit(this, d);
return (S) this;
}
default S writeStopBitDecimal(double d) throws BufferOverflowException {
boolean negative = d < 0;
double ad = Math.abs(d);
long value;
int scale = 0;
if ((long) ad == ad) {
value = (long) ad * 10;
} else {
double factor = 1;
while (scale < 9) {
double v = ad * factor;
if (v >= 1e14 || (long) v == v)
break;
factor *= 10;
scale++;
}
value = Math.round(ad * factor);
while (scale > 0 && value % 10 == 0) {
value /= 10;
scale--;
}
value = value * 10 + scale;
}
if (negative)
value = -value;
BytesInternal.writeStopBit(this, value);
return (S) this;
}
/**
* Write the same encoding as <code>writeUTF</code> with the following changes. 1) The length is stop bit encoded
* i.e. one byte longer for short strings, but is not limited in length. 2) The string can be null.
*
* @param cs the string value to be written. Can be null.
* @throws BufferOverflowException if there is not enough space left
*/
default S writeUtf8(CharSequence cs)
throws BufferOverflowException {
BytesInternal.writeUtf8(this, cs);
return (S) this;
}
default S writeUtf8(String s)
throws BufferOverflowException {
BytesInternal.writeUtf8(this, s);
return (S) this;
}
@Deprecated(/* to be removed in x.22 */)
default S writeUTFΔ(CharSequence cs) throws BufferOverflowException {
return writeUtf8(cs);
}
default S write8bit(CharSequence cs)
throws BufferOverflowException {
if (cs == null)
return writeStopBit(-1);
if (cs instanceof BytesStore)
return write8bit((BytesStore) cs);
if (cs instanceof String)
return write8bit((String) cs);
return write8bit(cs, 0, cs.length());
}
default S write8bit( CharSequence s, int start, int length)
throws BufferOverflowException, IllegalArgumentException, IndexOutOfBoundsException {
writeStopBit(length);
for (int i = 0; i < length; i++) {
char c = s.charAt(i + start);
rawWriteByte((byte) Maths.toUInt8((int) c));
}
return (S) this;
}
default S write(CharSequence cs)
throws BufferOverflowException, BufferUnderflowException, IllegalArgumentException {
if (cs instanceof BytesStore) {
return write((BytesStore) cs);
}
return write(cs, 0, cs.length());
}
default S write( CharSequence s, int start, int length)
throws BufferOverflowException, IllegalArgumentException, IndexOutOfBoundsException {
for (int i = 0; i < length; i++) {
char c = s.charAt(i + start);
appendUtf8(c);
}
return (S) this;
}
default S write8bit(String s)
throws BufferOverflowException {
if (s == null)
writeStopBit(-1);
else
write8bit(s, 0, (int) Math.min(writeRemaining(), s.length()));
return (S) this;
}
default S write8bit(BytesStore bs)
throws BufferOverflowException {
if (bs == null) {
writeStopBit(-1);
} else {
long offset = bs.readPosition();
long readRemaining = Math.min(writeRemaining(), bs.readLimit() - offset);
writeStopBit(readRemaining);
write(bs, offset, readRemaining);
}
return (S) this;
}
S writeByte(byte i8) throws BufferOverflowException;
default S rawWriteByte(byte i8) throws BufferOverflowException {
return writeByte(i8);
}
default S writeUnsignedByte(int i)
throws BufferOverflowException, IllegalArgumentException {
return writeByte((byte) Maths.toUInt8(i));
}
default S writeChar(char ch) {
return writeStopBit(ch);
}
S writeShort(short i16) throws BufferOverflowException;
default S writeUnsignedShort(int u16)
throws BufferOverflowException, IllegalArgumentException {
return writeShort((short) Maths.toUInt16(u16));
}
default S writeInt24(int i) throws BufferOverflowException {
writeUnsignedShort((short) i);
return writeUnsignedByte((i >>> 16) & 0xFF);
}
default S writeUnsignedInt24(int i) throws BufferOverflowException {
writeUnsignedShort((short) i);
return writeUnsignedByte(i >>> 16);
}
S writeInt(int i) throws BufferOverflowException;
default S rawWriteInt(int i) throws BufferOverflowException {
return writeInt(i);
}
S writeIntAdv(int i, int advance) throws BufferOverflowException;
default S writeUnsignedInt(long i)
throws BufferOverflowException, IllegalArgumentException {
return writeInt((int) Maths.toUInt32(i));
}
/**
* Write a long
*/
S writeLong(long i64) throws BufferOverflowException;
/**
* Write a long without a bounds check
*/
default S rawWriteLong(long i) throws BufferOverflowException {
return writeLong(i);
}
S writeLongAdv(long i64, int advance) throws BufferOverflowException;
S writeFloat(float f) throws BufferOverflowException;
S writeDouble(double d) throws BufferOverflowException;
S writeDoubleAndInt(double d, int i) throws BufferOverflowException;
/**
* Write all data or fail.
*/
default S write( RandomDataInput bytes) {
assert bytes != this : "you should not write to yourself !";
try {
return write(bytes, bytes.readPosition(), Math.min(writeRemaining(), bytes.readRemaining()));
} catch (BufferOverflowException | BufferUnderflowException e) {
throw new AssertionError(e);
}
}
/**
* Writes the passed BytesStore
*
* @param bytes to write
* @return this
*/
default S write( BytesStore bytes) {
assert bytes != this : "you should not write to yourself !";
try {
return write(bytes, bytes.readPosition(), Math.min(writeRemaining(), bytes.readRemaining()));
} catch (BufferOverflowException | BufferUnderflowException e) {
throw new AssertionError(e);
}
}
/**
* @return capacity without resize
*/
long realCapacity();
/**
* @return writeRemaining with resize
*/
long realWriteRemaining();
default boolean canWriteDirect(long count) {
return false;
}
default S writeSome( Bytes bytes) {
try {
long length = Math.min(bytes.readRemaining(), writeRemaining());
if (length + writePosition() >= 1 << 20)
length = Math.min(bytes.readRemaining(), realCapacity() - writePosition());
write(bytes, bytes.readPosition(), length);
if (length == bytes.readRemaining()) {
bytes.clear();
} else {
bytes.readSkip(length);
if (bytes.writePosition() > bytes.realCapacity() / 2)
bytes.compact();
}
return (S) this;
} catch (BufferOverflowException | BufferUnderflowException | IllegalArgumentException e) {
throw new AssertionError(e);
}
}
/**
* Write all data or fail.
*/
default S write( RandomDataInput bytes, long offset, long length)
throws BufferOverflowException, BufferUnderflowException {
BytesInternal.writeFully(bytes, offset, length, this);
return (S) this;
}
/**
* Write all data or fail.
*/
default S write( BytesStore bytes, long offset, long
length)
throws BufferOverflowException, BufferUnderflowException {
if (length + writePosition() > capacity())
throw new IllegalArgumentException("Cannot write " + length + " bytes as position is " + writePosition() + " and capacity is " + capacity());
BytesInternal.writeFully(bytes, offset, length, this);
return (S) this;
}
default S write( byte[] bytes) throws BufferOverflowException {
write(bytes, 0, bytes.length);
return (S) this;
}
/**
* Write all data or fail.
*/
S write(byte[] bytes, int offset, int length) throws BufferOverflowException;
default S unsafeWriteObject(Object o, int length) {
return unsafeWriteObject(o, (o.getClass().isArray() ? 4 : 0) + Jvm.objectHeaderSize(), length);
}
default S unsafeWriteObject(Object o, int offset, int length) {
int i = 0;
for (; i < length - 7; i += 8)
writeLong(UnsafeMemory.unsafeGetLong(o, offset + i));
for (; i < length; i++)
writeByte(UnsafeMemory.unsafeGetByte(o, offset + i));
return (S) this;
}
S writeSome(ByteBuffer buffer) throws BufferOverflowException;
default S writeBoolean(boolean flag) throws BufferOverflowException {
return writeByte(flag ? (byte) 'Y' : (byte) 'N');
}
S writeOrderedInt(int i) throws BufferOverflowException;
S writeOrderedLong(long i) throws BufferOverflowException;
default <E extends Enum<E>> S writeEnum( E e)
throws BufferOverflowException {
return write8bit(e.name());
}
default S appendUtf8( CharSequence cs)
throws BufferOverflowException {
return appendUtf8(cs, 0, cs.length());
}
default S appendUtf8(int codepoint) throws BufferOverflowException {
BytesInternal.appendUtf8Char(this, codepoint);
return (S) this;
}
default S appendUtf8(char[] chars, int offset, int length)
throws BufferOverflowException, IllegalArgumentException {
int i;
ascii:
{
for (i = 0; i < length; i++) {
char c = chars[offset + i];
if (c > 0x007F)
break ascii;
writeByte((byte) c);
}
return (S) this;
}
for (; i < length; i++) {
char c = chars[offset + i];
BytesInternal.appendUtf8Char(this, c);
}
return (S) this;
}
default S appendUtf8( CharSequence cs, int offset, int length)
throws BufferOverflowException, IllegalArgumentException {
BytesInternal.appendUtf8(this, cs, offset, length);
return (S) this;
}
// length is number of characters (not bytes)
@Java9
default S appendUtf8(byte[] bytes, int offset, int length, byte coder)
throws BufferOverflowException, IllegalArgumentException {
if (coder == JAVA9_STRING_CODER_LATIN) {
for (int i = 0; i < length; i++) {
byte b = bytes[offset + i];
int b2 = (b & 0xFF);
BytesInternal.appendUtf8Char(this, b2);
}
} else {
assert coder == JAVA9_STRING_CODER_UTF16;
for (int i = 0; i < 2 * length; i += 2) {
byte b1 = bytes[2 * offset + i];
byte b2 = bytes[2 * offset + i + 1];
int uBE = ((b2 & 0xFF) << 8) | b1 & 0xFF;
BytesInternal.appendUtf8Char(this, uBE);
}
}
return (S) this;
}
@Java9
default S appendUtf8(byte[] bytes, int offset, int length)
throws BufferOverflowException, IllegalArgumentException {
for (int i = 0; i < length; i++) {
int b = bytes[offset + i] & 0xFF; // unsigned byte
if (b >= 0xF0) {
int b2 = bytes[offset + i + 1] & 0xFF; // unsigned byte
int b3 = bytes[offset + i + 2] & 0xFF; // unsigned byte
int b4 = bytes[offset + i + 3] & 0xFF; // unsigned byte
this.writeByte((byte) b4);
this.writeByte((byte) b3);
this.writeByte((byte) b2);
this.writeByte((byte) b);
i += 3;
} else if (b >= 0xE0) {
int b2 = bytes[offset + i + 1] & 0xFF; // unsigned byte
int b3 = bytes[offset + i + 2] & 0xFF; // unsigned byte
this.writeByte((byte) b3);
this.writeByte((byte) b2);
this.writeByte((byte) b);
i += 2;
} else if (b >= 0xC0) {
int b2 = bytes[offset + i + 1] & 0xFF; // unsigned byte
this.writeByte((byte) b2);
this.writeByte((byte) b);
i += 1;
} else {
this.writeByte((byte) b);
}
}
return (S) this;
}
default void copyFrom( InputStream input) throws IOException, BufferOverflowException, IllegalArgumentException {
BytesInternal.copy(input, this);
}
default void writePositionRemaining(long position, long length) {
writeLimit(position + length);
writePosition(position);
}
default void writeHistogram( Histogram histogram) {
BytesInternal.writeHistogram(this, histogram);
}
default void writeBigDecimal( BigDecimal bd) {
writeBigInteger(bd.unscaledValue());
writeStopBit(bd.scale());
}
default void writeBigInteger( BigInteger bi) {
byte[] bytes = bi.toByteArray();
writeStopBit(bytes.length);
write(bytes);
}
default void writeWithLength(RandomDataInput bytes) {
writeStopBit(bytes.readRemaining());
write(bytes);
}
}

@ -1,70 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
@SuppressWarnings("rawtypes")
public class StreamingInputStream extends InputStream {
private StreamingDataInput in;
public StreamingInputStream() {
this(NoBytesStore.NO_BYTES);
}
public StreamingInputStream(StreamingDataInput in) {
this.in = in;
}
public StreamingInputStream init(StreamingDataInput in) {
this.in = in;
return this;
}
@Override
public long skip(long n) throws IOException {
long len = Math.min(in.readRemaining(), n);
in.readSkip(len);
return len;
}
@Override
public int available() throws IOException {
return (int) Math.min(Integer.MAX_VALUE, in.readRemaining());
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (len == 0) {
return 0;
}
int len2 = in.read(b, off, len);
return len2 == 0 ? -1 : len2;
}
@Override
public int read() throws IOException {
return in.readRemaining() > 0 ? in.readUnsignedByte() : -1;
}
}

@ -1,64 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
@SuppressWarnings("rawtypes")
public class StreamingOutputStream extends OutputStream {
private StreamingDataOutput sdo;
public StreamingOutputStream() {
this(NoBytesStore.NO_BYTES);
}
public StreamingOutputStream(StreamingDataOutput sdo) {
this.sdo = sdo;
}
public StreamingOutputStream init(StreamingDataOutput sdo) {
this.sdo = sdo;
return this;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
try {
sdo.write(b, off, len);
} catch ( BufferOverflowException | IllegalArgumentException e) {
throw new IOException(e);
}
}
@Override
public void write(int b) throws IOException {
try {
sdo.writeUnsignedByte(0xff & b);
} catch ( BufferOverflowException | IllegalArgumentException e) {
throw new IOException(e);
}
}
}

@ -1,58 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings({"rawtypes", "unchecked"})
public class SubBytes<Underlying> extends VanillaBytes<Underlying> {
private final long start;
private final long capacity;
public SubBytes( BytesStore bytesStore, long start, long capacity) throws IllegalStateException {
super(bytesStore);
this.start = start;
this.capacity = capacity;
clear();
readLimit(writeLimit());
}
public SubBytes( BytesStore bytesStore) throws IllegalStateException {
super(bytesStore);
this.start = 0;
this.capacity = bytesStore.capacity();
clear();
readLimit(writeLimit());
}
@Override
public long capacity() {
return capacity;
}
@Override
public long start() {
return start;
}
@Override
public long realCapacity() {
return capacity;
}
}

@ -1,31 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.io.IORuntimeException;
public class UTFDataFormatRuntimeException extends IORuntimeException {
public UTFDataFormatRuntimeException(String message) {
super(message);
}
public UTFDataFormatRuntimeException(String message, Exception cause) {
super(message, cause);
}
}

@ -1,294 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import static net.openhft.chronicle.core.util.StringUtils.extractBytes;
import static net.openhft.chronicle.core.util.StringUtils.extractChars;
/**
* Fast unchecked version of AbstractBytes
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class UncheckedBytes<Underlying>
extends AbstractBytes<Underlying> {
Bytes underlyingBytes;
public UncheckedBytes( Bytes underlyingBytes) throws IllegalStateException {
super(underlyingBytes.bytesStore(), underlyingBytes.writePosition(), underlyingBytes.writeLimit());
this.underlyingBytes = underlyingBytes;
readPosition(underlyingBytes.readPosition());
}
public void setBytes( Bytes bytes) throws IllegalStateException {
BytesStore underlyingBytes = bytes.bytesStore();
if (bytesStore != underlyingBytes) {
bytesStore.release(this);
this.bytesStore(underlyingBytes);
bytesStore.reserve(this);
}
readPosition(bytes.readPosition());
this.uncheckedWritePosition(bytes.writePosition());
this.writeLimit = bytes.writeLimit();
this.underlyingBytes = bytes;
}
@Override
public void ensureCapacity(long size) throws IllegalArgumentException {
if (size > realCapacity()) {
underlyingBytes.ensureCapacity(size);
bytesStore(underlyingBytes.bytesStore());
}
}
@Override
public Bytes<Underlying> unchecked(boolean unchecked) {
return this;
}
@Override
public boolean unchecked() {
return true;
}
@Override
void writeCheckOffset(long offset, long adding) {
}
@Override
void readCheckOffset(long offset, long adding, boolean given) {
}
@Override
void prewriteCheckOffset(long offset, long subtracting) {
}
@Override
public Bytes<Underlying> readPosition(long position) {
readPosition = position;
return this;
}
@Override
public Bytes<Underlying> readLimit(long limit) {
uncheckedWritePosition(limit);
return this;
}
@Override
public Bytes<Underlying> writePosition(long position) {
uncheckedWritePosition(position);
return this;
}
@Override
public Bytes<Underlying> readSkip(long bytesToSkip) {
readPosition += bytesToSkip;
return this;
}
@Override
public Bytes<Underlying> writeSkip(long bytesToSkip) {
uncheckedWritePosition(writePosition() + bytesToSkip);
return this;
}
@Override
public Bytes<Underlying> writeLimit(long limit) {
writeLimit = limit;
return this;
}
@Override
public BytesStore<Bytes<Underlying>, Underlying> copy() {
throw new UnsupportedOperationException("todo");
}
@Override
public boolean isElastic() {
return false;
}
@Override
protected long readOffsetPositionMoved(long adding) {
long offset = readPosition;
readPosition += adding;
return offset;
}
@Override
protected long writeOffsetPositionMoved(long adding, long advance) {
long oldPosition = writePosition();
uncheckedWritePosition(writePosition() + advance);
return oldPosition;
}
@Override
protected long prewriteOffsetPositionMoved(long subtracting) throws BufferOverflowException {
return readPosition -= subtracting;
}
@Override
public Bytes<Underlying> write( RandomDataInput bytes, long offset, long length)
throws BufferOverflowException, IllegalArgumentException {
if (length == 8) {
writeLong(bytes.readLong(offset));
} else {
super.write(bytes, offset, length);
}
return this;
}
public Bytes<Underlying> write( BytesStore bytes, long offset, long length)
throws BufferOverflowException, IllegalArgumentException {
if (length == 8) {
writeLong(bytes.readLong(offset));
} else if (bytes.underlyingObject() == null
&& bytesStore
.isDirectMemory() &&
length >= 32) {
rawCopy(bytes, offset, length);
} else {
super.write(bytes, offset, length);
}
return this;
}
@Override
public Bytes<Underlying> append8bit( CharSequence cs)
throws BufferOverflowException, BufferUnderflowException {
if (cs instanceof RandomDataInput) {
return write((RandomDataInput) cs);
}
int length = cs.length();
long offset = writeOffsetPositionMoved(length);
for (int i = 0; i < length; i++) {
char c = cs.charAt(i);
if (c > 255) c = '?';
writeByte(offset, (byte) c);
}
return this;
}
long rawCopy( BytesStore bytes, long offset, long length)
throws BufferOverflowException, IllegalArgumentException {
long len = Math.min(writeRemaining(), Math.min(bytes.capacity() - offset, length));
if (len > 0) {
writeCheckOffset(writePosition(), len);
this.throwExceptionIfReleased();
OS.memory().copyMemory(bytes.addressForRead(offset), addressForWritePosition(), len);
writeSkip(len);
}
return len;
}
@Override
public Bytes<Underlying> writeByte(byte i8) throws BufferOverflowException {
long offset = writeOffsetPositionMoved(1, 1);
bytesStore.writeByte(offset, i8);
return this;
}
@Override
public Bytes<Underlying> writeUtf8(String s) throws BufferOverflowException {
if (s == null) {
writeStopBit(-1);
return this;
}
try {
if (Jvm.isJava9Plus()) {
byte[] strBytes = extractBytes(s);
byte coder = StringUtils.getStringCoder(s);
long utfLength = AppendableUtil.findUtf8Length(strBytes, coder);
writeStopBit(utfLength);
appendUtf8(strBytes, 0, s.length(), coder);
} else {
char[] chars = extractChars(s);
long utfLength = AppendableUtil.findUtf8Length(chars);
writeStopBit(utfLength);
if (utfLength == chars.length)
append8bit(chars);
else
appendUtf8(chars, 0, chars.length);
}
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
return this;
}
void append8bit(char[] chars) throws BufferOverflowException, IllegalArgumentException {
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
bytesStore.writeByte(writePosition++, (byte) c);
}
}
@Override
public Bytes<Underlying> appendUtf8(char[] chars, int offset, int length) throws BufferOverflowException, IllegalArgumentException {
int i;
ascii:
{
for (i = 0; i < length; i++) {
char c = chars[offset + i];
if (c > 0x007F)
break ascii;
bytesStore.writeByte(writePosition++, (byte) c);
}
return this;
}
for (; i < length; i++) {
char c = chars[offset + i];
BytesInternal.appendUtf8Char(this, c);
}
return this;
}
@Override
public void write(long offsetInRDO, ByteBuffer bytes, int offset, int length) throws BufferOverflowException {
}
}

@ -1,930 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.algo.BytesStoreHash;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Memory;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.io.AbstractReferenceCounted;
import net.openhft.chronicle.core.io.BackgroundResourceReleaser;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
/**
* Fast unchecked version of AbstractBytes
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class UncheckedNativeBytes<Underlying>
extends AbstractReferenceCounted
implements Bytes<Underlying> {
protected final long capacity;
private final Bytes<Underlying> underlyingBytes;
protected NativeBytesStore<Underlying> bytesStore;
protected long readPosition;
protected long writePosition;
protected long writeLimit;
private int lastDecimalPlaces = 0;
public UncheckedNativeBytes( Bytes<Underlying> underlyingBytes)
throws IllegalStateException {
this.underlyingBytes = underlyingBytes;
underlyingBytes.reserve(this);
this.bytesStore = (NativeBytesStore<Underlying>) underlyingBytes.bytesStore();
assert bytesStore.start() == 0;
writePosition = underlyingBytes.writePosition();
writeLimit = underlyingBytes.writeLimit();
readPosition = underlyingBytes.readPosition();
capacity = bytesStore.capacity();
}
@Override
public void ensureCapacity(long size) throws IllegalArgumentException {
if (size > realCapacity()) {
underlyingBytes.ensureCapacity(size);
bytesStore = (NativeBytesStore<Underlying>) underlyingBytes.bytesStore();
}
}
@Override
public boolean unchecked() {
return true;
}
@Override
public boolean isDirectMemory() {
return true;
}
@Override
public Bytes<Underlying> unchecked(boolean unchecked) {
return this;
}
@Override
public void move(long from, long to, long length) {
bytesStore.move(from - start(), to - start(), length);
}
@Override
public Bytes<Underlying> compact() {
long start = start();
long readRemaining = readRemaining();
if (readRemaining > 0 && start < readPosition) {
bytesStore.move(readPosition, start, readRemaining);
readPosition = start;
writePosition = readPosition + readRemaining;
}
return this;
}
@Override
public Bytes<Underlying> readPosition(long position) {
readPosition = position;
return this;
}
@Override
public Bytes<Underlying> readLimit(long limit) {
writePosition = limit;
return this;
}
@Override
public Bytes<Underlying> writePosition(long position) {
writePosition = position;
return this;
}
@Override
public Bytes<Underlying> readSkip(long bytesToSkip) {
readPosition += bytesToSkip;
return this;
}
@Override
public byte readVolatileByte(long offset) throws BufferUnderflowException {
return bytesStore.readVolatileByte(offset);
}
@Override
public short readVolatileShort(long offset) throws BufferUnderflowException {
return bytesStore.readVolatileShort(offset);
}
@Override
public int readVolatileInt(long offset) throws BufferUnderflowException {
return bytesStore.readVolatileInt(offset);
}
@Override
public long readVolatileLong(long offset) throws BufferUnderflowException {
return bytesStore.readVolatileLong(offset);
}
@Override
public void uncheckedReadSkipOne() {
readPosition++;
}
@Override
public void uncheckedReadSkipBackOne() {
readPosition--;
}
@Override
public Bytes<Underlying> writeSkip(long bytesToSkip) {
writePosition += bytesToSkip;
return this;
}
@Override
public Bytes<Underlying> writeLimit(long limit) {
writeLimit = limit;
return this;
}
@Override
public BytesStore<Bytes<Underlying>, Underlying> copy() {
throw new UnsupportedOperationException("todo");
}
@Override
public boolean isElastic() {
return false;
}
protected long readOffsetPositionMoved(long adding) {
long offset = readPosition;
readPosition += adding;
return offset;
}
protected long writeOffsetPositionMoved(long adding) {
return writeOffsetPositionMoved(adding, adding);
}
protected long writeOffsetPositionMoved(long adding, long advance) {
long oldPosition = writePosition;
long writeEnd = oldPosition + adding;
assert writeEnd <= bytesStore.safeLimit();
writePosition += advance;
return oldPosition;
}
protected long prewriteOffsetPositionMoved(long substracting) {
return readPosition -= substracting;
}
@Override
public Bytes<Underlying> write( RandomDataInput bytes, long offset, long length)
throws BufferUnderflowException, BufferOverflowException {
if (length == 8) {
writeLong(bytes.readLong(offset));
} else if (length >= 16 && bytes.isDirectMemory()) {
rawCopy(bytes, offset, length);
} else {
BytesInternal.writeFully(bytes, offset, length, this);
}
return this;
}
public long rawCopy( RandomDataInput bytes, long offset, long length)
throws BufferOverflowException, BufferUnderflowException {
long len = Math.min(writeRemaining(), Math.min(bytes.capacity() - offset, length));
if (len > 0) {
writeCheckOffset(writePosition(), len);
this.throwExceptionIfReleased();
OS.memory().copyMemory(bytes.addressForRead(offset), addressForWritePosition(), len);
writeSkip(len);
}
return len;
}
@Override
public Bytes<Underlying> clear() {
readPosition = writePosition = start();
writeLimit = capacity();
return this;
}
@Override
public Bytes<Underlying> clearAndPad(long length) throws BufferOverflowException {
if (start() + length > capacity())
throw new BufferOverflowException();
readPosition = writePosition = start() + length;
writeLimit = capacity();
return this;
}
@Override
@ForceInline
public long readLimit() {
return writePosition;
}
@Override
@ForceInline
public long writeLimit() {
return writeLimit;
}
@Override
@ForceInline
public long realCapacity() {
return bytesStore.realCapacity();
}
@Override
public long realWriteRemaining() {
return writeRemaining();
}
@Override
@ForceInline
public long capacity() {
return capacity;
}
@Override
public Underlying underlyingObject() {
return bytesStore.underlyingObject();
}
@Override
@ForceInline
public long readPosition() {
return readPosition;
}
@Override
@ForceInline
public long writePosition() {
return writePosition;
}
@Override
@ForceInline
public boolean compareAndSwapInt(long offset, int expected, int value)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
return bytesStore.compareAndSwapInt(offset, expected, value);
}
@Override
public void testAndSetInt(long offset, int expected, int value) {
writeCheckOffset(offset, 4);
bytesStore.testAndSetInt(offset, expected, value);
}
@Override
@ForceInline
public boolean compareAndSwapLong(long offset, long expected, long value)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
return bytesStore.compareAndSwapLong(offset, expected, value);
}
@Override
protected void performRelease() {
this.underlyingBytes.release(this);
// need to wait as checks rely on this completing.
BackgroundResourceReleaser.releasePendingResources();
}
@Override
public int readUnsignedByte() {
long offset = readOffsetPositionMoved(1);
return bytesStore.memory.readByte(bytesStore.address + offset) & 0xFF;
}
@Override
public int uncheckedReadUnsignedByte() {
return readUnsignedByte();
}
@Override
@ForceInline
public byte readByte() {
long offset = readOffsetPositionMoved(1);
return bytesStore.memory.readByte(bytesStore.address + offset);
}
@Override
@ForceInline
public int peekUnsignedByte() {
try {
return readRemaining() > 0 ? bytesStore.readUnsignedByte(readPosition) : -1;
} catch (BufferUnderflowException e) {
return -1;
}
}
@Override
@ForceInline
public short readShort() {
long offset = readOffsetPositionMoved(2);
return bytesStore.readShort(offset);
}
@Override
@ForceInline
public int readInt() {
long offset = readOffsetPositionMoved(4);
return bytesStore.readInt(offset);
}
@Override
@ForceInline
public long readLong() {
long offset = readOffsetPositionMoved(8);
return bytesStore.readLong(offset);
}
@Override
@ForceInline
public float readFloat() {
long offset = readOffsetPositionMoved(4);
return bytesStore.readFloat(offset);
}
@Override
@ForceInline
public double readDouble() {
long offset = readOffsetPositionMoved(8);
return bytesStore.readDouble(offset);
}
@Override
@ForceInline
public int readVolatileInt() {
long offset = readOffsetPositionMoved(4);
return bytesStore.readVolatileInt(offset);
}
@Override
@ForceInline
public long readVolatileLong() {
long offset = readOffsetPositionMoved(8);
return bytesStore.readVolatileLong(offset);
}
@Override
@ForceInline
public Bytes<Underlying> writeByte(long offset, byte i) throws BufferOverflowException {
writeCheckOffset(offset, 1);
bytesStore.writeByte(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeShort(long offset, short i) throws BufferOverflowException {
writeCheckOffset(offset, 2);
bytesStore.writeShort(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeInt(long offset, int i) throws BufferOverflowException {
writeCheckOffset(offset, 4);
bytesStore.writeInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeOrderedInt(long offset, int i) throws BufferOverflowException {
writeCheckOffset(offset, 4);
bytesStore.writeOrderedInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeLong(long offset, long i) throws BufferOverflowException {
writeCheckOffset(offset, 8);
bytesStore.writeLong(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeOrderedLong(long offset, long i) throws BufferOverflowException {
writeCheckOffset(offset, 8);
bytesStore.writeOrderedLong(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeFloat(long offset, float d) throws BufferOverflowException {
writeCheckOffset(offset, 4);
bytesStore.writeFloat(offset, d);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeDouble(long offset, double d) throws BufferOverflowException {
writeCheckOffset(offset, 8);
bytesStore.writeDouble(offset, d);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeVolatileByte(long offset, byte i8)
throws BufferOverflowException {
writeCheckOffset(offset, 1);
bytesStore.writeVolatileByte(offset, i8);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeVolatileShort(long offset, short i16)
throws BufferOverflowException {
writeCheckOffset(offset, 2);
bytesStore.writeVolatileShort(offset, i16);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeVolatileInt(long offset, int i32)
throws BufferOverflowException {
writeCheckOffset(offset, 4);
bytesStore.writeVolatileInt(offset, i32);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeVolatileLong(long offset, long i64)
throws BufferOverflowException {
writeCheckOffset(offset, 8);
bytesStore.writeVolatileLong(offset, i64);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> write(long offsetInRDO, byte[] bytes, int offset, int length)
throws BufferOverflowException {
writeCheckOffset(offsetInRDO, length);
bytesStore.write(offsetInRDO, bytes, offset, length);
return this;
}
@Override
@ForceInline
public void write(long offsetInRDO, ByteBuffer bytes, int offset, int length) throws BufferOverflowException {
writeCheckOffset(offsetInRDO, length);
bytesStore.write(offsetInRDO, bytes, offset, length);
}
@Override
@ForceInline
public Bytes<Underlying> write(long writeOffset,
RandomDataInput bytes, long readOffset, long length)
throws BufferUnderflowException, BufferOverflowException {
writeCheckOffset(writeOffset, length);
bytesStore.write(writeOffset, bytes, readOffset, length);
return this;
}
@ForceInline
void writeCheckOffset(long offset, long adding) throws BufferOverflowException {
// assert writeCheckOffset0(offset, adding);
}
@Override
@ForceInline
public byte readByte(long offset) {
return bytesStore.readByte(offset);
}
@Override
public int readUnsignedByte(long offset) {
return bytesStore.memory.readByte(bytesStore.address + offset) & 0xFF;
}
@Override
public int peekUnsignedByte(long offset) {
return offset >= writePosition ? -1 : readByte(offset);
}
@Override
@ForceInline
public short readShort(long offset) {
return bytesStore.readShort(offset);
}
@Override
@ForceInline
public int readInt(long offset) {
return bytesStore.readInt(offset);
}
@Override
@ForceInline
public long readLong(long offset) {
return bytesStore.readLong(offset);
}
@Override
@ForceInline
public float readFloat(long offset) {
return bytesStore.readFloat(offset);
}
@Override
@ForceInline
public double readDouble(long offset) {
return bytesStore.readDouble(offset);
}
@Override
@ForceInline
public Bytes<Underlying> writeByte(byte i8) {
long offset = writeOffsetPositionMoved(1);
bytesStore.memory.writeByte(bytesStore.address + offset, i8);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewriteByte(byte i8) {
long offset = prewriteOffsetPositionMoved(1);
bytesStore.memory.writeByte(bytesStore.address + offset, i8);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeShort(short i16) {
long offset = writeOffsetPositionMoved(2);
bytesStore.writeShort(offset, i16);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewriteShort(short i16) {
long offset = prewriteOffsetPositionMoved(2);
bytesStore.writeShort(offset, i16);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeInt(int i) {
long offset = writeOffsetPositionMoved(4);
bytesStore.writeInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeIntAdv(int i, int advance) {
long offset = writeOffsetPositionMoved(4, advance);
bytesStore.writeInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewriteInt(int i) {
long offset = prewriteOffsetPositionMoved(4);
bytesStore.writeInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeLong(long i64) {
long offset = writeOffsetPositionMoved(8);
bytesStore.writeLong(offset, i64);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeLongAdv(long i64, int advance) {
long offset = writeOffsetPositionMoved(8, advance);
bytesStore.writeLong(offset, i64);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewriteLong(long i64) {
long offset = prewriteOffsetPositionMoved(8);
bytesStore.writeLong(offset, i64);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeFloat(float f) {
long offset = writeOffsetPositionMoved(4);
bytesStore.writeFloat(offset, f);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeDouble(double d) {
long offset = writeOffsetPositionMoved(8);
bytesStore.writeDouble(offset, d);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeDoubleAndInt(double d, int i) {
long offset = writeOffsetPositionMoved(12);
bytesStore.writeDouble(offset, d);
bytesStore.writeInt(offset + 8, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> write( byte[] bytes, int offset, int length) {
if (length + offset > bytes.length)
throw new ArrayIndexOutOfBoundsException("bytes.length=" + bytes.length + ", " +
"length=" + length + ", offset=" + offset);
if (length > writeRemaining())
throw new BufferOverflowException();
long offsetInRDO = writeOffsetPositionMoved(length);
bytesStore.write(offsetInRDO, bytes, offset, length);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewrite( byte[] bytes) {
long offsetInRDO = prewriteOffsetPositionMoved(bytes.length);
bytesStore.write(offsetInRDO, bytes);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> prewrite( BytesStore bytes) {
long offsetInRDO = prewriteOffsetPositionMoved(bytes.length());
bytesStore.write(offsetInRDO, bytes);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeSome( ByteBuffer buffer) {
bytesStore.write(writePosition, buffer, buffer.position(), buffer.limit());
writePosition += buffer.remaining();
assert writePosition <= writeLimit();
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeOrderedInt(int i) {
long offset = writeOffsetPositionMoved(4);
bytesStore.writeOrderedInt(offset, i);
return this;
}
@Override
@ForceInline
public Bytes<Underlying> writeOrderedLong(long i) {
long offset = writeOffsetPositionMoved(8);
bytesStore.writeOrderedLong(offset, i);
return this;
}
@Override
public long addressForRead(long offset) throws BufferUnderflowException {
return bytesStore.addressForRead(offset);
}
@Override
public long addressForWrite(long offset) throws BufferOverflowException {
return bytesStore.addressForWrite(offset);
}
@Override
public long addressForWritePosition() throws UnsupportedOperationException, BufferOverflowException {
return bytesStore.addressForWrite(0);
}
@Override
public int hashCode() {
return BytesStoreHash.hash32(this);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Bytes)) return false;
Bytes b2 = (Bytes) obj;
long remaining = readRemaining();
return b2.readRemaining() == remaining && equalsBytes(b2, remaining);
}
public boolean equalsBytes( Bytes b2, long remaining) {
long i = 0;
try {
for (; i < remaining - 7; i += 8)
if (readLong(readPosition() + i) != b2.readLong(b2.readPosition() + i))
return false;
for (; i < remaining; i++)
if (readByte(readPosition() + i) != b2.readByte(b2.readPosition() + i))
return false;
} catch (BufferUnderflowException e) {
throw Jvm.rethrow(e);
}
return true;
}
@Override
public String toString() {
return BytesInternal.toString(this);
}
@Override
public void lenient(boolean lenient) {
throw new UnsupportedOperationException();
}
@Override
public boolean lenient() {
return false;
}
@Override
@ForceInline
public void nativeRead(long position, long address, long size) {
bytesStore.nativeRead(position, address, size);
}
@Override
@ForceInline
public void nativeWrite(long address, long position, long size) {
bytesStore.nativeWrite(address, position, size);
}
@Override
public BytesStore bytesStore() {
return bytesStore;
}
@Override
public int byteCheckSum() throws IORuntimeException {
NativeBytesStore bytesStore = (NativeBytesStore) bytesStore();
return bytesStore.byteCheckSum(readPosition(), readLimit());
}
@Override
public Bytes<Underlying> append8bit( CharSequence cs)
throws BufferOverflowException, BufferUnderflowException {
if (cs instanceof BytesStore) {
return write((BytesStore) cs);
}
int length = cs.length();
long offset = writeOffsetPositionMoved(length);
long address = bytesStore.addressForWrite(offset);
Memory memory = bytesStore.memory;
assert memory != null;
try {
int i = 0;
for (; i < length - 1; i += 2) {
char c = cs.charAt(i);
char c2 = cs.charAt(i + 1);
memory.writeByte(address + i, (byte) c);
memory.writeByte(address + i + 1, (byte) c2);
}
for (; i < length; i++) {
char c = cs.charAt(i);
memory.writeByte(address + i, (byte) c);
}
return this;
} catch (IndexOutOfBoundsException e) {
throw new AssertionError(e);
}
}
@Override
public Bytes<Underlying> appendUtf8(char[] chars, int offset, int length) throws BufferOverflowException, IllegalArgumentException {
ensureCapacity(length);
NativeBytesStore nbs = this.bytesStore;
long position = nbs.appendUtf8(writePosition(), chars, offset, length);
writePosition(position);
return this;
}
@Override
public int lastDecimalPlaces() {
return lastDecimalPlaces;
}
@Override
public void lastDecimalPlaces(int lastDecimalPlaces) {
this.lastDecimalPlaces = Math.max(0, lastDecimalPlaces);
}
@Override
public Bytes<Underlying> write( RandomDataInput bytes) {
assert bytes != this : "you should not write to yourself !";
try {
return write(bytes, bytes.readPosition(), Math.min(writeRemaining(), bytes.readRemaining()));
} catch (BufferOverflowException | BufferUnderflowException e) {
throw new AssertionError(e);
}
}
}

@ -1,18 +0,0 @@
package net.openhft.chronicle.bytes;
/**
* Represents an operation that accepts a single input argument then modifies that same instance.
*/
@FunctionalInterface
public interface UpdateInterceptor {
/**
* modifies {@code t} with changed data
*
* @param methodName the name of the method
* @param t the input argument - for a method call with multiple arguments, the last one is passed
* @return whether to proceed. If false, don't write
*/
boolean update(String methodName, Object t);
}

@ -1,597 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.Memory;
import net.openhft.chronicle.core.OS;
import net.openhft.chronicle.core.annotation.Java9;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import static net.openhft.chronicle.bytes.NoBytesStore.noBytesStore;
/**
* Simple Bytes implementation which is not Elastic.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class VanillaBytes<Underlying>
extends AbstractBytes<Underlying>
implements Byteable<Bytes<Underlying>, Underlying>, Comparable<CharSequence> {
public VanillaBytes( BytesStore bytesStore) throws IllegalStateException {
this(bytesStore, bytesStore.writePosition(), bytesStore.writeLimit());
}
public VanillaBytes( BytesStore bytesStore, long writePosition, long writeLimit) throws IllegalStateException {
super(bytesStore, writePosition, writeLimit);
}
/**
* @return a non elastic bytes.
*/
public static VanillaBytes<Void> vanillaBytes() {
try {
return new VanillaBytes<>(noBytesStore());
} catch (IllegalStateException e) {
throw new AssertionError(e);
}
}
@Java9
private static boolean isEqual0( byte[] bytes, byte coder, NativeBytesStore bs, long address) {
Memory memory = bs.memory;
if (coder == 0) {
int i = 0;
for (; i < bytes.length; i++) {
byte b = memory.readByte(address + i);
char c = (char) (bytes[i] & 0xFF);
if (b != c) {
return false;
}
}
} else {
int i = 0;
for (; i < bytes.length; i++) {
byte b = memory.readByte(address + i);
char c = (char) (((bytes[i + 1] & 0xFF) << 8) | (bytes[i] & 0xFF));
if (b != c) {
return false;
}
}
}
return true;
}
private static boolean isEqual0( char[] chars, NativeBytesStore bs, long address) {
Memory memory = bs.memory;
int i = 0;
for (; i < chars.length - 3; i += 4) {
int b = memory.readInt(address + i);
int b0 = b & 0xFF;
int b1 = (b >> 8) & 0xFF;
int b2 = (b >> 16) & 0xFF;
int b3 = (b >> 24) & 0xFF;
if (b0 != chars[i] || b1 != chars[i + 1] || b2 != chars[i + 2] || b3 != chars[i + 3])
return false;
}
for (; i < chars.length; i++) {
int b = memory.readByte(address + i) & 0xFF;
if (b != chars[i])
return false;
}
return true;
}
private static boolean isEqual1( char[] chars, BytesStore bytesStore, long readPosition) throws BufferUnderflowException {
for (int i = 0; i < chars.length; i++) {
int b = bytesStore.readByte(readPosition + i) & 0xFF;
if (b != chars[i])
return false;
}
return true;
}
@Java9
private static boolean isEqual1( byte[] bytes, byte coder, BytesStore bytesStore, long readPosition) throws BufferUnderflowException {
for (int i = 0; i < bytes.length; i++) {
int b = bytesStore.readByte(readPosition + i) & 0xFF;
char c;
if (coder == 0) {
c = (char) (bytes[i] & 0xFF);
} else {
c = (char) (((bytes[i + 1] & 0xFF) << 8) | (bytes[i] & 0xFF));
i++;
}
if (b != c)
return false;
}
return true;
}
@Override
public long readVolatileLong(long offset) throws BufferUnderflowException {
readCheckOffset(offset, 8, true);
return bytesStore.readVolatileLong(offset);
}
@Override
public void bytesStore( BytesStore<Bytes<Underlying>, Underlying> byteStore, long offset, long length)
throws IllegalStateException, BufferOverflowException, BufferUnderflowException {
setBytesStore(byteStore);
// assume its read-only
readLimit(offset + length);
writeLimit(offset + length);
readPosition(offset);
}
private void setBytesStore( BytesStore<Bytes<Underlying>, Underlying> bytesStore)
throws IllegalStateException {
if (this.bytesStore != bytesStore) {
BytesStore oldBS = this.bytesStore;
this.bytesStore(bytesStore);
bytesStore.reserve(this);
oldBS.release(this);
}
clear();
}
@Override
public long offset() {
return readPosition();
}
@Override
public long maxSize() {
return readRemaining();
}
@Override
public boolean isElastic() {
return false;
}
@Override
public Bytes<Underlying> bytesForRead() throws IllegalStateException {
return isClear()
? new VanillaBytes<>(bytesStore, writePosition(), bytesStore.writeLimit())
: new SubBytes<>(bytesStore, readPosition(), readLimit());
}
@Override
public boolean isEqual( String s) {
if (s == null || s.length() != readRemaining()) return false;
try {
if (Jvm.isJava9Plus()) {
byte[] bytes = StringUtils.extractBytes(s);
byte coder = StringUtils.getStringCoder(s);
if (bytesStore instanceof NativeBytesStore) {
NativeBytesStore bs = (NativeBytesStore) this.bytesStore;
long address = bs.addressForRead(readPosition);
return isEqual0(bytes, coder, bs, address);
} else {
return isEqual1(bytes, coder, bytesStore, readPosition);
}
} else {
char[] chars = StringUtils.extractChars(s);
if (bytesStore instanceof NativeBytesStore) {
NativeBytesStore bs = (NativeBytesStore) this.bytesStore;
long address = bs.addressForRead(readPosition);
return isEqual0(chars, bs, address);
} else {
return isEqual1(chars, bytesStore, readPosition);
}
}
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
}
@Override
public long realCapacity() {
return bytesStore.realCapacity();
}
@Override
public BytesStore<Bytes<Underlying>, Underlying> copy() {
if (bytesStore.underlyingObject() instanceof ByteBuffer) {
try {
ByteBuffer bb = ByteBuffer.allocateDirect(Maths.toInt32(readRemaining()));
ByteBuffer bbu = (ByteBuffer) bytesStore.underlyingObject();
ByteBuffer slice = bbu.slice();
slice.position((int) readPosition());
slice.limit((int) readLimit());
bb.put(slice);
bb.clear();
return (BytesStore) BytesStore.wrap(bb);
} catch (IllegalArgumentException e) {
throw new AssertionError(e);
}
} else {
return (BytesStore) NativeBytes.copyOf(this);
}
}
@Override
public Bytes<Underlying> write( RandomDataInput bytes, long offset, long length)
throws BufferOverflowException, BufferUnderflowException, IllegalArgumentException {
optimisedWrite(bytes, offset, length);
return this;
}
protected void optimisedWrite( RandomDataInput bytes, long offset, long length) {
if (length <= safeCopySize() && isDirectMemory() && bytes.isDirectMemory()) {
long len = Math.min(writeRemaining(), Math.min(bytes.capacity() - offset, length));
if (len > 0) {
writeCheckOffset(writePosition(), len);
long address = bytes.addressForRead(offset);
long address2 = addressForWritePosition();
assert address != 0;
assert address2 != 0;
OS.memory().copyMemory(address, address2, len);
writeSkip(len);
}
} else {
super.write(bytes, offset, length);
}
}
public void write(long position, CharSequence str, int offset, int length)
throws BufferOverflowException, IllegalArgumentException {
ensureCapacity(length);
if (offset + length > str.length())
throw new IllegalArgumentException("offset=" + offset + " + length=" + length + " > str.length =" + str.length());
for (int i = 0; i < length; i++) {
bytesStore.writeByte(position + i, str.charAt(offset + i));
}
}
@Override
public VanillaBytes append( CharSequence str, int start, int end) throws IndexOutOfBoundsException {
assert end > start : "end=" + end + ",start=" + start;
try {
if (isDirectMemory()) {
if (str instanceof BytesStore) {
write((BytesStore) str, (long) start, end - start);
return this;
}
if (str instanceof String) {
if (Jvm.isJava9Plus()) {
byte coder = StringUtils.getStringCoder((String) str);
appendUtf8(StringUtils.extractBytes((String) str), start, end - start, coder);
} else {
appendUtf8(StringUtils.extractChars((String) str), start, end - start);
}
return this;
}
}
super.append(str, start, end);
return this;
} catch (Exception e) {
throw new IndexOutOfBoundsException(e.toString());
}
}
@Override
public VanillaBytes appendUtf8( CharSequence str) throws BufferOverflowException {
try {
if (isDirectMemory()) {
if (str instanceof BytesStore) {
write((BytesStore) str, 0L, str.length());
return this;
}
if (str instanceof String) {
if (Jvm.isJava9Plus()) {
String str1 = (String) str;
byte coder = StringUtils.getStringCoder(str1);
appendUtf8(StringUtils.extractBytes(str1), 0, str.length(), coder);
} else {
appendUtf8(StringUtils.extractChars((String) str), 0, str.length());
}
return this;
}
}
super.append(str, 0, str.length());
return this;
} catch (Exception e) {
BufferOverflowException e2 = new BufferOverflowException();
e2.initCause(e);
throw e2;
}
}
@Override
public Bytes<Underlying> append8bit( CharSequence cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
if (cs instanceof RandomDataInput)
return write((RandomDataInput) cs);
if (isDirectMemory() && cs instanceof String)
return append8bitNBS_S((String) cs);
return append8bit0(cs);
}
@Override
public Bytes<Underlying> append8bit( BytesStore bs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
long remaining = bs.readLimit() - bs.readPosition();
return write(bs, 0L, remaining);
}
@Override
public Bytes<Underlying> write( BytesStore bytes, long offset, long length) throws BufferOverflowException, BufferUnderflowException {
if (bytes.canReadDirect(length) && canWriteDirect(length) && length == (int) length) {
long wAddr = addressForWritePosition();
writeSkip(length);
long rAddr = bytes.addressForRead(offset);
BytesInternal.copyMemory(rAddr, wAddr, (int) length);
} else {
BytesInternal.writeFully(bytes, offset, length, this);
}
return this;
}
@Override
public Bytes<Underlying> append8bit( String cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
if (isDirectMemory())
return append8bitNBS_S(cs);
return append8bit0(cs);
}
private Bytes<Underlying> append8bitNBS_S( String s) throws BufferOverflowException {
int length = s.length();
long offset = writeOffsetPositionMoved(length); // can re-assign the byteStore if not large enough.
NativeBytesStore bytesStore = (NativeBytesStore) this.bytesStore;
final long address = bytesStore.address + bytesStore.translate(offset);
final Memory memory = bytesStore.memory;
if (memory == null)
bytesStore.throwExceptionIfReleased();
if (Jvm.isJava9Plus()) {
final byte[] chars = StringUtils.extractBytes(s);
int i;
for (i = 0; i < length; i++) {
memory.writeByte(address + i, chars[i]);
}
} else {
final char[] chars = StringUtils.extractChars(s);
int i;
for (i = 0; i < length - 3; i += 4) {
int c0 = chars[i] & 0xFF;
int c1 = chars[i + 1] & 0xFF;
int c2 = chars[i + 2] & 0xFF;
int c3 = chars[i + 3] & 0xFF;
memory.writeInt(address + i, c0 | (c1 << 8) | (c2 << 16) | (c3 << 24));
}
for (; i < length; i++) {
int c0 = chars[i];
memory.writeByte(address + i, (byte) c0);
}
}
return this;
}
public String toString() {
return bytesStore instanceof NativeBytesStore
? toString2((NativeBytesStore) bytesStore)
: toString0();
}
private String toString2( NativeBytesStore bytesStore) {
int length = (int)
Math.min(Bytes.MAX_HEAP_CAPACITY, readRemaining());
char[] chars = new char[length];
final Memory memory = bytesStore.memory;
final long address = bytesStore.address + bytesStore.translate(readPosition());
for (int i = 0; i < length && i < realCapacity(); i++)
chars[i] = (char) (memory.readByte(address + i) & 0xFF);
return StringUtils.newString(chars);
}
protected String toString0() {
int length = (int) Math.min(Bytes.MAX_HEAP_CAPACITY, readRemaining());
char[] chars = new char[length];
try {
for (int i = 0; i < length; i++) {
chars[i] = (char) (bytesStore.readByte(readPosition() + i) & 0xFF);
}
} catch (BufferUnderflowException e) {
// ignored
}
return StringUtils.newString(chars);
}
protected Bytes<Underlying> append8bit0( CharSequence cs) throws BufferOverflowException, IndexOutOfBoundsException {
int length = cs.length();
long offset = writeOffsetPositionMoved(length);
for (int i = 0; i < length; i++) {
char c = cs.charAt(i);
if (c > 255) c = '?';
bytesStore.writeByte(offset + i, (byte) c);
}
return this;
}
@Override
public boolean equalBytes( BytesStore bytesStore, long length) throws BufferUnderflowException {
if (isDirectMemory() &&
bytesStore instanceof VanillaBytes &&
bytesStore.isDirectMemory()) {
VanillaBytes b2 = (VanillaBytes) bytesStore;
NativeBytesStore nbs0 = (NativeBytesStore) this.bytesStore;
NativeBytesStore nbs2 = (NativeBytesStore) b2.bytesStore();
long i = 0;
for (; i < length - 7; i += 8) {
long addr0 = nbs0.address + readPosition() - nbs0.start() + i;
long addr2 = nbs2.address + b2.readPosition() - nbs2.start() + i;
long l0 = nbs0.memory.readLong(addr0);
long l2 = nbs2.memory.readLong(addr2);
if (l0 != l2)
return false;
}
for (; i < length; i++) {
long offset2 = readPosition() + i - nbs0.start();
long offset21 = b2.readPosition() + i - nbs2.start();
byte b0 = nbs0.memory.readByte(nbs0.address + offset2);
byte b1 = nbs2.memory.readByte(nbs2.address + offset21);
if (b0 != b1)
return false;
}
return true;
} else {
return super.equalBytes(bytesStore, length);
}
}
public void read8Bit(char[] chars, int length) {
if (isDirectMemory()) {
long position = readPosition();
NativeBytesStore nbs = (NativeBytesStore) bytesStore();
nbs.read8bit(position, chars, length);
} else {
long pos = this.readPosition();
for (int i = 0; i < length; i++)
chars[i] = (char) this.readUnsignedByte(pos + i);
}
}
// TODO: protected?
@Override
public int byteCheckSum(int start, int end) throws IORuntimeException {
byte b = 0;
// the below cast is safe as should only be called from net.openhft.chronicle.bytes.AbstractBytes.byteCheckSum(long, long)
NativeBytesStore bytesStore = (NativeBytesStore) bytesStore();
Memory memory = bytesStore.memory;
assert memory != null;
long addr = bytesStore.addressForRead(start);
int i = 0, len = end - start;
for (; i < len - 3; i += 4) {
b += memory.readByte(addr + i)
+ memory.readByte(addr + i + 1)
+ memory.readByte(addr + i + 2)
+ memory.readByte(addr + i + 3);
}
for (; i < len; i++) {
b += memory.readByte(addr + i);
}
return b & 0xFF;
}
@Override
public Bytes<Underlying> appendUtf8(char[] chars, int offset, int length) throws BufferOverflowException, IllegalArgumentException {
ensureCapacity(length);
if (bytesStore instanceof NativeBytesStore) {
NativeBytesStore nbs = (NativeBytesStore) this.bytesStore;
long position = nbs.appendUtf8(writePosition(), chars, offset, length);
writePosition(position);
} else {
super.appendUtf8(chars, offset, length);
}
return this;
}
@Override
public ByteBuffer toTemporaryDirectByteBuffer() throws IllegalArgumentException {
if (isClear())
return bytesStore.toTemporaryDirectByteBuffer();
return super.toTemporaryDirectByteBuffer();
}
@Override
public int read( byte[] bytes) {
int len = (int) Math.min(bytes.length, readRemaining());
if (bytesStore instanceof NativeBytesStore) {
NativeBytesStore nbs = (NativeBytesStore) this.bytesStore;
long len2 = nbs.read(readPosition(), bytes, 0, len);
try {
readSkip(len2);
} catch (BufferUnderflowException e) {
throw new AssertionError(e);
}
return (int) (len2);
}
return super.read(bytes);
}
@Override
public int compareTo( CharSequence cs) {
long len1 = readRemaining();
int len2 = cs.length();
long lim = Math.min(len1, len2);
int k = 0;
while (k < lim) {
char c1 = bytesStore.charAt(k);
char c2 = cs.charAt(k);
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return (int) (len1 - len2);
}
}

@ -1,36 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.annotation.DontChain;
/**
* Write data directly as Bytes.
*/
@SuppressWarnings("rawtypes")
@FunctionalInterface
@DontChain
public interface WriteBytesMarshallable extends CommonMarshallable {
/**
* Write to Bytes. This can be used as an interface to extend or a lambda
*
* @param bytes to write to.
*/
void writeMarshallable(BytesOut bytes);
}

@ -1,54 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.algo;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.bytes.NativeBytesStore;
import java.util.function.ToLongFunction;
/**
* Simple function to derive a long hash from a BytesStore
*/
@SuppressWarnings("rawtypes")
public interface BytesStoreHash<B extends BytesStore> extends ToLongFunction<B> {
static long hash( BytesStore b) {
return b.isDirectMemory() && b.bytesStore() instanceof NativeBytesStore
? OptimisedBytesStoreHash.INSTANCE.applyAsLong(b)
: VanillaBytesStoreHash.INSTANCE.applyAsLong(b);
}
static long hash( BytesStore b, long length) {
return b.isDirectMemory() && b.bytesStore() instanceof NativeBytesStore
? OptimisedBytesStoreHash.INSTANCE.applyAsLong(b, length)
: VanillaBytesStoreHash.INSTANCE.applyAsLong(b, length);
}
static int hash32(BytesStore b) {
long hash = hash(b);
return (int) (hash ^ (hash >>> 32));
}
static int hash32( BytesStore b, int length) {
long hash = hash(b, length);
return (int) (hash ^ (hash >>> 32));
}
long applyAsLong(BytesStore bytes, long length);
}

@ -1,274 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.algo;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.bytes.NativeBytesStore;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.Memory;
import net.openhft.chronicle.core.OS;
import java.nio.ByteOrder;
import static net.openhft.chronicle.bytes.algo.VanillaBytesStoreHash.*;
@SuppressWarnings("rawtypes")
public enum OptimisedBytesStoreHash implements BytesStoreHash<BytesStore> {
INSTANCE;
public static final Memory MEMORY = OS.memory();
public static final boolean IS_LITTLE_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
private static final int TOP_BYTES = IS_LITTLE_ENDIAN ? 4 : 0;
static long applyAsLong1to7( BytesStore store, int remaining) {
final long address = store.addressForRead(store.readPosition());
return hash(readIncompleteLong(address, remaining));
}
static long applyAsLong8( BytesStore store) {
final long address = store.addressForRead(store.readPosition());
return hash0(MEMORY.readLong(address), MEMORY.readInt(address + TOP_BYTES));
}
public static long hash(long l) {
return hash0(l, l >> 32);
}
static long hash0(long l, long hi) {
return agitate(l * K0 + hi * K1);
}
static long applyAsLong9to16( BytesStore store, int remaining) {
final NativeBytesStore bytesStore = (NativeBytesStore) store.bytesStore();
final long address = bytesStore.addressForRead(store.readPosition());
long h0 = (long) remaining * K0;
int left = remaining;
long addrI = address;
long l0 = readIncompleteLong(addrI, left);
int l0a = (int) (l0 >> 32);
long l1 = readIncompleteLong(addrI + 8, left - 8);
int l1a = (int) (l1 >> 32);
final long l2 = 0;
final int l2a = 0;
final long l3 = 0;
final int l3a = 0;
h0 += (l0 + l1a - l2a) * M0;
long h1 = (l1 + l2a - l3a) * M1;
long h2 = (l2 + l3a - l0a) * M2;
long h3 = (l3 + l0a - l1a) * M3;
return agitate(h0) ^ agitate(h1)
^ agitate(h2) ^ agitate(h3);
}
static long applyAsLong17to32( BytesStore store, int remaining) {
final NativeBytesStore bytesStore = (NativeBytesStore) store.bytesStore();
final long address = bytesStore.addressForRead(store.readPosition());
long h0 = (long) remaining * K0;
int left = remaining;
long addrI = address;
long l0 = MEMORY.readLong(addrI);
int l0a = MEMORY.readInt(addrI + TOP_BYTES);
long l1 = MEMORY.readLong(addrI + 8);
int l1a = MEMORY.readInt(addrI + 8 + TOP_BYTES);
long l2 = readIncompleteLong(addrI + 16, left - 16);
int l2a = (int) (l2 >> 32);
long l3 = readIncompleteLong(addrI + 24, left - 24);
int l3a = (int) (l3 >> 32);
h0 += (l0 + l1a - l2a) * M0;
long h1 = (l1 + l2a - l3a) * M1;
long h2 = (l2 + l3a - l0a) * M2;
long h3 = (l3 + l0a - l1a) * M3;
return agitate(h0) ^ agitate(h1)
^ agitate(h2) ^ agitate(h3);
}
public static long applyAsLong32bytesMultiple( BytesStore store, int remaining) {
final NativeBytesStore bytesStore = (NativeBytesStore) store.bytesStore();
final long address = bytesStore.addressForRead(store.readPosition());
long h0 = remaining * K0, h1 = 0, h2 = 0, h3 = 0;
int i;
for (i = 0; i < remaining - 31; i += 32) {
if (i > 0) {
h0 *= K0;
h1 *= K1;
h2 *= K2;
h3 *= K3;
}
long addrI = address + i;
long l0 = MEMORY.readLong(addrI);
int l0a = MEMORY.readInt(addrI + TOP_BYTES);
long l1 = MEMORY.readLong(addrI + 8);
int l1a = MEMORY.readInt(addrI + 8 + TOP_BYTES);
long l2 = MEMORY.readLong(addrI + 16);
int l2a = MEMORY.readInt(addrI + 16 + TOP_BYTES);
long l3 = MEMORY.readLong(addrI + 24);
int l3a = MEMORY.readInt(addrI + 24 + TOP_BYTES);
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
}
return agitate(h0) ^ agitate(h1)
^ agitate(h2) ^ agitate(h3);
}
public static long applyAsLongAny( BytesStore store, long remaining) {
final NativeBytesStore bytesStore = (NativeBytesStore) store.bytesStore();
final long address = bytesStore.addressForRead(store.readPosition());
long h0 = remaining * K0, h1 = 0, h2 = 0, h3 = 0;
int i;
for (i = 0; i < remaining - 31; i += 32) {
if (i > 0) {
h0 *= K0;
h1 *= K1;
h2 *= K2;
h3 *= K3;
}
long addrI = address + i;
long l0 = MEMORY.readLong(addrI);
int l0a = MEMORY.readInt(addrI + TOP_BYTES);
long l1 = MEMORY.readLong(addrI + 8);
int l1a = MEMORY.readInt(addrI + 8 + TOP_BYTES);
long l2 = MEMORY.readLong(addrI + 16);
int l2a = MEMORY.readInt(addrI + 16 + TOP_BYTES);
long l3 = MEMORY.readLong(addrI + 24);
int l3a = MEMORY.readInt(addrI + 24 + TOP_BYTES);
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
}
long left = remaining - i;
if (left > 0) {
if (i > 0) {
h0 *= K0;
h1 *= K1;
h2 *= K2;
h3 *= K3;
}
long addrI = address + i;
if (left <= 16) {
long l0 = readIncompleteLong(addrI, (int) left);
int l0a = (int) (l0 >> 32);
long l1 = readIncompleteLong(addrI + 8, (int) (left - 8));
int l1a = (int) (l1 >> 32);
final long l2 = 0;
final int l2a = 0;
final long l3 = 0;
final int l3a = 0;
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
} else {
long l0 = MEMORY.readLong(addrI);
int l0a = MEMORY.readInt(addrI + TOP_BYTES);
long l1 = MEMORY.readLong(addrI + 8);
int l1a = MEMORY.readInt(addrI + 8 + TOP_BYTES);
long l2 = readIncompleteLong(addrI + 16, (int) (left - 16));
int l2a = (int) (l2 >> 32);
long l3 = readIncompleteLong(addrI + 24, (int) (left - 24));
int l3a = (int) (l3 >> 32);
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
}
}
return agitate(h0) ^ agitate(h1)
^ agitate(h2) ^ agitate(h3);
}
static long readIncompleteLong(long address, int len) {
switch (len) {
case 1:
return MEMORY.readByte(address);
case 2:
return MEMORY.readShort(address);
case 3:
return IS_LITTLE_ENDIAN
? (MEMORY.readShort(address) & 0xFFFF) + ((MEMORY.readByte(address + 2) & 0xFF) << 16)
: ((MEMORY.readShort(address) & 0xFFFF) << 8) + (MEMORY.readByte(address + 2) & 0xFF);
case 4:
return MEMORY.readInt(address);
case 5:
return IS_LITTLE_ENDIAN
? (MEMORY.readInt(address) & 0xFFFFFFFFL) + ((long) (MEMORY.readByte(address + 4) & 0xFF) << 32)
: ((MEMORY.readInt(address) & 0xFFFFFFFFL) << 8) + (MEMORY.readByte(address + 4) & 0xFF);
case 6:
return IS_LITTLE_ENDIAN
? (MEMORY.readInt(address) & 0xFFFFFFFFL) + ((long) (MEMORY.readShort(address + 4) & 0xFFFF) << 32)
: ((MEMORY.readInt(address) & 0xFFFFFFFFL) << 16) + (MEMORY.readShort(address + 4) & 0xFFFF);
case 7:
return IS_LITTLE_ENDIAN
? (MEMORY.readInt(address) & 0xFFFFFFFFL) + ((long) (MEMORY.readShort(address + 4) & 0xFFFF) << 32) + ((long) (MEMORY.readByte(address + 6) & 0xFF) << 48)
: ((MEMORY.readInt(address) & 0xFFFFFFFFL) << 24) + ((MEMORY.readShort(address + 4) & 0xFFFF) << 8) + (MEMORY.readByte(address + 6) & 0xFF);
default:
return len >= 8 ? MEMORY.readLong(address) : 0;
}
}
@Override
public long applyAsLong( BytesStore store) {
final int remaining = Maths.toInt32(store.readRemaining());
return applyAsLong(store, remaining);
}
@Override
public long applyAsLong( BytesStore store, long remaining) {
if (remaining <= 16) {
if (remaining == 0) {
return 0;
} else if (remaining < 8) {
return applyAsLong1to7(store, (int) remaining);
} else if (remaining == 8) {
return applyAsLong8(store);
} else {
return applyAsLong9to16(store, (int) remaining);
}
} else if (remaining <= 32) {
return applyAsLong17to32(store, (int) remaining);
} else if ((remaining & 31) == 0) {
return applyAsLong32bytesMultiple(store, (int) remaining);
} else {
return applyAsLongAny(store, remaining);
}
}
}

@ -1,116 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.algo;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.core.Maths;
import org.jetbrains.annotations.NotNull;
import java.nio.ByteOrder;
@SuppressWarnings("rawtypes")
public enum VanillaBytesStoreHash implements BytesStoreHash<BytesStore> {
INSTANCE;
public static final int K0 = 0x6d0f27bd;
public static final int K1 = 0xc1f3bfc9;
public static final int K2 = 0x6b192397;
public static final int K3 = 0x6b915657;
public static final int M0 = 0x5bc80bad;
public static final int M1 = 0xea7585d7;
public static final int M2 = 0x7a646e19;
public static final int M3 = 0x855dd4db;
private static final int HI_BYTES = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? 4 : 0;
public static long agitate(long l) {
l ^= Long.rotateLeft(l, 26);
l ^= Long.rotateRight(l, 17);
return l;
}
@Override
public long applyAsLong( BytesStore store) {
int remaining = Maths.toInt32(store.readRemaining());
return applyAsLong(store, remaining);
}
@Override
public long applyAsLong(BytesStore bytes, long length) {
long start = bytes.readPosition();
if (length <= 8) {
long l = bytes.readIncompleteLong(start);
return agitate(l * K0 + (l >> 32) * K1);
}
// use two hashes so that when they are combined the 64-bit hash is more random.
long h0 = length * K0;
long h1 = 0, h2 = 0, h3 = 0;
int i;
// optimise chunks of 32 bytes but this is the same as the next loop.
for (i = 0; i < length - 31; i += 32) {
if (i > 0) {
h0 *= K0;
h1 *= K1;
h2 *= K2;
h3 *= K3;
}
long addrI = start + i;
long l0 = bytes.readLong(addrI);
int l0a = bytes.readInt(addrI + HI_BYTES);
long l1 = bytes.readLong(addrI + 8);
int l1a = bytes.readInt(addrI + 8 + HI_BYTES);
long l2 = bytes.readLong(addrI + 16);
int l2a = bytes.readInt(addrI + 16 + HI_BYTES);
long l3 = bytes.readLong(addrI + 24);
int l3a = bytes.readInt(addrI + 24 + HI_BYTES);
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
}
// perform a hash of the end.
long left = length - i;
if (left > 0) {
if (i > 0) {
h0 *= K0;
h1 *= K1;
h2 *= K2;
h3 *= K3;
}
long addrI = start + i;
long l0 = bytes.readIncompleteLong(addrI);
int l0a = (int) (l0 >> 32);
long l1 = bytes.readIncompleteLong(addrI + 8);
int l1a = (int) (l1 >> 32);
long l2 = bytes.readIncompleteLong(addrI + 16);
int l2a = (int) (l2 >> 32);
long l3 = bytes.readIncompleteLong(addrI + 24);
int l3a = (int) (l3 >> 32);
h0 += (l0 + l1a - l2a) * M0;
h1 += (l1 + l2a - l3a) * M1;
h2 += (l2 + l3a - l0a) * M2;
h3 += (l3 + l0a - l1a) * M3;
}
return agitate(h0) ^ agitate(h1)
^ agitate(h2) ^ agitate(h3);
}
}

@ -1,161 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.algo;
import net.openhft.chronicle.bytes.BytesStore;
// Migration of XxHash from Zero-Allocation-Hashing
@SuppressWarnings("rawtypes")
public class XxHash implements BytesStoreHash<BytesStore> {
// Primes if treated as unsigned
private static final long P1 = -7046029288634856825L;
private static final long P2 = -4417276706812531889L;
private static final long P3 = 1609587929392839161L;
private static final long P4 = -8796714831421723037L;
public static final XxHash INSTANCE = new XxHash(P4);
private static final long P5 = 2870177450012600261L;
private final long seed;
public XxHash(long seed) {
this.seed = seed;
}
private static long finalize(long hash) {
hash ^= hash >>> 33;
hash *= P2;
hash ^= hash >>> 29;
hash *= P3;
hash ^= hash >>> 32;
return hash;
}
long fetch64(BytesStore bytes, long off) {
return bytes.readLong(off);
}
// long because of unsigned nature of original algorithm
long fetch32(BytesStore bytes, long off) {
return bytes.readUnsignedInt(off);
}
// int because of unsigned nature of original algorithm
long fetch8(BytesStore bytes, long off) {
return bytes.readUnsignedByte(off);
}
@Override
public long applyAsLong(BytesStore bytes) {
return applyAsLong(bytes, bytes.readRemaining());
}
@Override
public long applyAsLong(BytesStore bytes, long length) {
long hash;
long remaining = length;
long off = bytes.readPosition();
if (remaining >= 32) {
long v1 = seed + P1 + P2;
long v2 = seed + P2;
long v3 = seed;
long v4 = seed - P1;
do {
v1 += fetch64(bytes, off) * P2;
v1 = Long.rotateLeft(v1, 31);
v1 *= P1;
v2 += fetch64(bytes, off + 8) * P2;
v2 = Long.rotateLeft(v2, 31);
v2 *= P1;
v3 += fetch64(bytes, off + 16) * P2;
v3 = Long.rotateLeft(v3, 31);
v3 *= P1;
v4 += fetch64(bytes, off + 24) * P2;
v4 = Long.rotateLeft(v4, 31);
v4 *= P1;
off += 32;
remaining -= 32;
} while (remaining >= 32);
hash = Long.rotateLeft(v1, 1)
+ Long.rotateLeft(v2, 7)
+ Long.rotateLeft(v3, 12)
+ Long.rotateLeft(v4, 18);
v1 *= P2;
v1 = Long.rotateLeft(v1, 31);
v1 *= P1;
hash ^= v1;
hash = hash * P1 + P4;
v2 *= P2;
v2 = Long.rotateLeft(v2, 31);
v2 *= P1;
hash ^= v2;
hash = hash * P1 + P4;
v3 *= P2;
v3 = Long.rotateLeft(v3, 31);
v3 *= P1;
hash ^= v3;
hash = hash * P1 + P4;
v4 *= P2;
v4 = Long.rotateLeft(v4, 31);
v4 *= P1;
hash ^= v4;
hash = hash * P1 + P4;
} else {
hash = seed + P5;
}
hash += length;
while (remaining >= 8) {
long k1 = fetch64(bytes, off);
k1 *= P2;
k1 = Long.rotateLeft(k1, 31);
k1 *= P1;
hash ^= k1;
hash = Long.rotateLeft(hash, 27) * P1 + P4;
off += 8;
remaining -= 8;
}
if (remaining >= 4) {
hash ^= fetch32(bytes, off) * P1;
hash = Long.rotateLeft(hash, 23) * P2 + P3;
off += 4;
remaining -= 4;
}
while (remaining != 0) {
hash ^= fetch8(bytes, off) * P5;
hash = Long.rotateLeft(hash, 11) * P1;
--remaining;
++off;
}
return finalize(hash);
}
}

@ -1,16 +0,0 @@
/**
* This package and any and all sub-packages contains strictly internal classes for this Chronicle library.
* Internal classes shall <em>never</em> be used directly.
* <p>
* Specifically, the following actions (including, but not limited to) are not allowed
* on internal classes and packages:
* <ul>
* <li>Casting to</li>
* <li>Reflection of any kind</li>
* <li>Explicit Serialize/deserialize</li>
* </ul>
* <p>
* The classes in this package and any sub-package are subject to
* changes at any time for any reason.
*/
package net.openhft.chronicle.bytes.internal;

@ -1,48 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.pool;
import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.core.io.IOTools;
import org.jetbrains.annotations.NotNull;
import java.nio.ByteBuffer;
@SuppressWarnings("rawtypes")
public class BytesPool {
final ThreadLocal<Bytes> bytesTL = new ThreadLocal<>();
public Bytes acquireBytes() {
Bytes bytes = bytesTL.get();
if (bytes == null) {
bytesTL.set(bytes = createBytes());
} else {
bytes.clear();
}
return bytes;
}
protected Bytes createBytes() {
// use heap buffer as we never know when a thread will die and not release this resource.
Bytes<ByteBuffer> bbb = Bytes.elasticHeapByteBuffer(256);
IOTools.unmonitor(bbb);
return bbb;
}
}

@ -1,93 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.Byteable;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.core.io.AbstractCloseable;
import net.openhft.chronicle.core.io.Closeable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@SuppressWarnings("rawtypes")
public abstract class AbstractReference extends AbstractCloseable implements Byteable, Closeable {
protected BytesStore<?, ?> bytes;
protected long offset;
@Override
public void bytesStore( final BytesStore bytes, final long offset, final long length) throws IllegalStateException, IllegalArgumentException, BufferOverflowException, BufferUnderflowException {
throwExceptionIfClosedInSetter();
acceptNewBytesStore(bytes);
this.offset = offset;
}
@Override
public BytesStore bytesStore() {
return bytes;
}
@Override
public long offset() {
return offset;
}
@Override
public abstract long maxSize();
protected void acceptNewBytesStore( final BytesStore bytes) {
if (this.bytes != null) {
this.bytes.release(this);
}
this.bytes = bytes.bytesStore();
this.bytes.reserve(this);
}
@Override
protected void performClose() {
if (this.bytes != null) {
this.bytes.release(this);
this.bytes = null;
}
}
public long address() {
throwExceptionIfClosed();
return bytesStore().addressForRead(offset);
}
/* TODO FIX
@Override
protected void finalize() throws Throwable {
warnIfNotClosed();
super.finalize();
}*/
@Override
protected boolean threadSafetyCheck(boolean isUsed) {
// References are thread safe
return true;
}
}

@ -1,51 +0,0 @@
package net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.core.values.BooleanValue;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
public class BinaryBooleanReference extends AbstractReference implements BooleanValue {
private static final byte FALSE = (byte) 0xB0;
private static final byte TRUE = (byte) 0xB1;
@SuppressWarnings("rawtypes")
@Override
public void bytesStore( final BytesStore bytes, final long offset, final long length) throws IllegalStateException, IllegalArgumentException, BufferOverflowException, BufferUnderflowException {
throwExceptionIfClosedInSetter();
if (length != maxSize())
throw new IllegalArgumentException();
super.bytesStore(bytes, offset, length);
}
@Override
public long maxSize() {
return 1;
}
@Override
public boolean getValue() {
throwExceptionIfClosed();
byte b = bytes.readByte(offset);
if (b == FALSE)
return false;
if (b == TRUE)
return true;
throw new IllegalStateException("unexpected code=" + b);
}
@Override
public void setValue(final boolean flag) {
throwExceptionIfClosed();
bytes.writeByte(offset, flag ? TRUE : FALSE);
}
}

@ -1,282 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.*;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.values.IntValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import static net.openhft.chronicle.bytes.ref.BinaryIntReference.INT_NOT_COMPLETE;
/**
* This class acts a Binary array of 64-bit values. c.f. TextLongArrayReference
*/
@SuppressWarnings("rawtypes")
public class BinaryIntArrayReference extends AbstractReference implements ByteableIntArrayValues, BytesMarshallable {
public static final int SHIFT = 2;
private static final long CAPACITY = 0;
private static final long USED = CAPACITY + Long.BYTES;
private static final long VALUES = USED + Long.BYTES;
private static final int MAX_TO_STRING = 1024;
private static Set<WeakReference<BinaryIntArrayReference>> binaryIntArrayReferences = null;
private long length;
public BinaryIntArrayReference() {
this(0);
}
public BinaryIntArrayReference(long defaultCapacity) {
this.length = (defaultCapacity << SHIFT) + VALUES;
}
public static void startCollecting() {
binaryIntArrayReferences = Collections.newSetFromMap(new IdentityHashMap<>());
}
public static void forceAllToNotCompleteState() {
binaryIntArrayReferences.forEach(x -> {
BinaryIntArrayReference binaryLongReference = x.get();
if (binaryLongReference != null) {
binaryLongReference.setValueAt(0, INT_NOT_COMPLETE);
}
});
binaryIntArrayReferences = null;
}
public static void write( Bytes bytes, long capacity) throws BufferOverflowException, IllegalArgumentException {
assert (bytes.writePosition() & 0x7) == 0;
bytes.writeLong(capacity);
bytes.writeLong(0L); // used
long start = bytes.writePosition();
bytes.zeroOut(start, start + (capacity << SHIFT));
bytes.writeSkip(capacity << SHIFT);
}
public static void lazyWrite( Bytes bytes, long capacity) throws BufferOverflowException {
assert (bytes.writePosition() & 0x7) == 0;
bytes.writeLong(capacity);
bytes.writeLong(0L); // used
bytes.writeSkip(capacity << SHIFT);
}
public static long peakLength( BytesStore bytes, long offset) throws BufferUnderflowException {
final long capacity = bytes.readLong(offset + CAPACITY);
assert capacity > 0 : "capacity too small " + capacity;
return (capacity << SHIFT) + VALUES;
}
@Override
public long getCapacity() {
throwExceptionIfClosed();
return (length - VALUES) >>> SHIFT;
}
@Override
public long getUsed() {
throwExceptionIfClosed();
return bytes.readVolatileInt(offset + USED);
}
@Override
public void setMaxUsed(long usedAtLeast) {
throwExceptionIfClosedInSetter();
bytes.writeMaxLong(offset + USED, usedAtLeast);
}
@Override
public int getValueAt(long index) throws BufferUnderflowException {
throwExceptionIfClosed();
return bytes.readInt(VALUES + offset + (index << SHIFT));
}
@Override
public void setValueAt(long index, int value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosedInSetter();
bytes.writeInt(VALUES + offset + (index << SHIFT), value);
}
@Override
public int getVolatileValueAt(long index) throws BufferUnderflowException {
throwExceptionIfClosed();
return bytes.readVolatileInt(VALUES + offset + (index << SHIFT));
}
@Override
public void bindValueAt(long index, IntValue value) {
throwExceptionIfClosed();
((BinaryIntReference) value).bytesStore(bytes, VALUES + offset + (index << SHIFT), 8);
}
@Override
public void setOrderedValueAt(long index, int value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosedInSetter();
bytes.writeOrderedInt(VALUES + offset + (index << SHIFT), value);
}
@Override
public void bytesStore( BytesStore bytes, long offset, long length) throws BufferUnderflowException, IllegalArgumentException {
throwExceptionIfClosed();
if (length != peakLength(bytes, offset))
throw new IllegalArgumentException(length + " != " + peakLength(bytes, offset));
assert (offset & 7) == 0 : "offset=" + offset;
super.bytesStore(bytes, (offset + 7) & ~7, length);
this.length = length;
}
@Override
public void readMarshallable(BytesIn bytes) throws IORuntimeException {
throwExceptionIfClosedInSetter();
long position = bytes.readPosition();
long capacity = bytes.readLong();
long used = bytes.readLong();
if (capacity < 0 || capacity > bytes.readRemaining() >> SHIFT)
throw new IORuntimeException("Corrupt used capacity");
if (used < 0 || used > capacity)
throw new IORuntimeException("Corrupt used value");
bytes.readSkip(capacity << SHIFT);
long length = bytes.readPosition() - position;
bytesStore(((Bytes) bytes).bytesStore(), position, length);
}
@Override
public void writeMarshallable(BytesOut bytes) {
BytesStore bytesStore = bytesStore();
if (bytesStore == null) {
long capacity = getCapacity();
bytes.writeLong(capacity);
bytes.writeLong(0);
bytes.writeSkip(capacity << SHIFT);
} else {
bytes.write(bytesStore, offset, length);
}
}
@Override
public boolean isNull() {
throwExceptionIfClosed();
return bytes == null;
}
@Override
public void reset() {
throwExceptionIfClosedInSetter();
bytes = null;
offset = 0;
length = 0;
}
@Override
public BytesStore bytesStore() {
return bytes;
}
@Override
public long offset() {
return offset;
}
@Override
public long maxSize() {
return length;
}
public String toString() {
if (bytes == null)
return "not set";
StringBuilder sb = new StringBuilder();
sb.append("used: ");
long used = getUsed();
sb.append(used);
sb.append(", value: ");
String sep = "";
try {
int i, max = (int) Math.min(used, Math.min(getCapacity(), MAX_TO_STRING));
for (i = 0; i < max; i++) {
long valueAt = getValueAt(i);
sb.append(sep).append(valueAt);
sep = ", ";
}
if (i < getCapacity())
sb.append(" ...");
} catch (BufferUnderflowException e) {
sb.append(" ").append(e);
}
return sb.toString();
}
@Override
public long sizeInBytes(long capacity) {
throwExceptionIfClosed();
return (capacity << SHIFT) + VALUES;
}
@Override
public ByteableIntArrayValues capacity(long arrayLength) {
throwExceptionIfClosedInSetter();
BytesStore bytesStore = bytesStore();
long length = sizeInBytes(arrayLength);
if (bytesStore == null) {
this.length = length;
} else {
assert this.length == length;
}
return this;
}
@Override
public boolean compareAndSet(long index, int expected, int value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosed();
if (value == INT_NOT_COMPLETE && binaryIntArrayReferences != null)
binaryIntArrayReferences.add(new WeakReference<>(this));
return bytes.compareAndSwapInt(VALUES + offset + (index << SHIFT), expected, value);
}
}

@ -1,101 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.core.values.IntValue;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
/**
* This class acts as a Binary 32-bit in values. c.f. TextIntReference
*/
public class BinaryIntReference extends AbstractReference implements IntValue {
public static final int INT_NOT_COMPLETE = Integer.MIN_VALUE;
@SuppressWarnings("rawtypes")
@Override
public void bytesStore( final BytesStore bytes, final long offset, final long length) throws IllegalStateException, IllegalArgumentException, BufferOverflowException, BufferUnderflowException {
throwExceptionIfClosedInSetter();
if (length != maxSize())
throw new IllegalArgumentException();
super.bytesStore(bytes, offset, length);
}
@Override
public long maxSize() {
return 4;
}
public String toString() {
return bytes == null ? "bytes is null" : "value: " + getValue();
}
@Override
public int getValue() {
throwExceptionIfClosed();
return bytes == null ? 0 : bytes.readInt(offset);
}
@Override
public void setValue(int value) {
throwExceptionIfClosedInSetter();
bytes.writeInt(offset, value);
}
@Override
public int getVolatileValue() {
throwExceptionIfClosed();
return bytes.readVolatileInt(offset);
}
@Override
public void setOrderedValue(int value) {
throwExceptionIfClosedInSetter();
bytes.writeOrderedInt(offset, value);
}
@Override
public int addValue(int delta) {
throwExceptionIfClosed();
return bytes.addAndGetInt(offset, delta);
}
@Override
public int addAtomicValue(int delta) {
throwExceptionIfClosed();
return addValue(delta);
}
@Override
public boolean compareAndSwapValue(int expected, int value) {
throwExceptionIfClosed();
return bytes.compareAndSwapInt(offset, expected, value);
}
}

@ -1,282 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.*;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.values.LongValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import static net.openhft.chronicle.bytes.ref.BinaryLongReference.LONG_NOT_COMPLETE;
/**
* This class acts a Binary array of 64-bit values. c.f. TextLongArrayReference
*/
@SuppressWarnings("rawtypes")
public class BinaryLongArrayReference extends AbstractReference implements ByteableLongArrayValues, BytesMarshallable {
public static final int SHIFT = 3;
private static final long CAPACITY = 0;
private static final long USED = CAPACITY + Long.BYTES;
private static final long VALUES = USED + Long.BYTES;
private static final int MAX_TO_STRING = 1024;
private static Set<WeakReference<BinaryLongArrayReference>> binaryLongArrayReferences = null;
private long length;
public BinaryLongArrayReference() {
this(0);
}
public BinaryLongArrayReference(long defaultCapacity) {
this.length = (defaultCapacity << SHIFT) + VALUES;
}
public static void startCollecting() {
binaryLongArrayReferences = Collections.newSetFromMap(new IdentityHashMap<>());
}
public static void forceAllToNotCompleteState() {
binaryLongArrayReferences.forEach(x -> {
BinaryLongArrayReference binaryLongReference = x.get();
if (binaryLongReference != null) {
binaryLongReference.setValueAt(0, LONG_NOT_COMPLETE);
}
});
binaryLongArrayReferences = null;
}
public static void write( Bytes bytes, long capacity) throws BufferOverflowException, IllegalArgumentException {
assert (bytes.writePosition() & 0x7) == 0;
bytes.writeLong(capacity);
bytes.writeLong(0L); // used
long start = bytes.writePosition();
bytes.zeroOut(start, start + (capacity << SHIFT));
bytes.writeSkip(capacity << SHIFT);
}
public static void lazyWrite( Bytes bytes, long capacity) throws BufferOverflowException {
assert (bytes.writePosition() & 0x7) == 0;
bytes.writeLong(capacity);
bytes.writeLong(0L); // used
bytes.writeSkip(capacity << SHIFT);
}
public static long peakLength( BytesStore bytes, long offset) throws BufferUnderflowException {
final long capacity = bytes.readLong(offset + CAPACITY);
assert capacity > 0 : "capacity too small " + capacity;
return (capacity << SHIFT) + VALUES;
}
@Override
public long getCapacity() {
throwExceptionIfClosed();
return (length - VALUES) >>> SHIFT;
}
@Override
public long getUsed() {
throwExceptionIfClosed();
return bytes.readVolatileLong(offset + USED);
}
@Override
public void setMaxUsed(long usedAtLeast) {
throwExceptionIfClosedInSetter();
bytes.writeMaxLong(offset + USED, usedAtLeast);
}
@Override
public long getValueAt(long index) throws BufferUnderflowException {
throwExceptionIfClosed();
return bytes.readLong(VALUES + offset + (index << SHIFT));
}
@Override
public void setValueAt(long index, long value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosedInSetter();
bytes.writeLong(VALUES + offset + (index << SHIFT), value);
}
@Override
public long getVolatileValueAt(long index) throws BufferUnderflowException {
throwExceptionIfClosed();
return bytes.readVolatileLong(VALUES + offset + (index << SHIFT));
}
@Override
public void bindValueAt(long index, LongValue value) {
throwExceptionIfClosed();
((BinaryLongReference) value).bytesStore(bytes, VALUES + offset + (index << SHIFT), 8);
}
@Override
public void setOrderedValueAt(long index, long value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosedInSetter();
bytes.writeOrderedLong(VALUES + offset + (index << SHIFT), value);
}
@Override
public void bytesStore( BytesStore bytes, long offset, long length) throws BufferUnderflowException, IllegalArgumentException {
throwExceptionIfClosed();
if (length != peakLength(bytes, offset))
throw new IllegalArgumentException(length + " != " + peakLength(bytes, offset));
assert (offset & 7) == 0 : "offset=" + offset;
super.bytesStore(bytes, (offset + 7) & ~7, length);
this.length = length;
}
@Override
public void readMarshallable(BytesIn bytes) throws IORuntimeException {
throwExceptionIfClosedInSetter();
long position = bytes.readPosition();
long capacity = bytes.readLong();
long used = bytes.readLong();
if (capacity < 0 || capacity > bytes.readRemaining() >> SHIFT)
throw new IORuntimeException("Corrupt used capacity");
if (used < 0 || used > capacity)
throw new IORuntimeException("Corrupt used value");
bytes.readSkip(capacity << SHIFT);
long length = bytes.readPosition() - position;
bytesStore(((Bytes) bytes).bytesStore(), position, length);
}
@Override
public void writeMarshallable(BytesOut bytes) {
BytesStore bytesStore = bytesStore();
if (bytesStore == null) {
long capacity = getCapacity();
bytes.writeLong(capacity);
bytes.writeLong(0);
bytes.writeSkip(capacity << SHIFT);
} else {
bytes.write(bytesStore, offset, length);
}
}
@Override
public boolean isNull() {
throwExceptionIfClosed();
return bytes == null;
}
@Override
public void reset() {
throwExceptionIfClosedInSetter();
bytes = null;
offset = 0;
length = 0;
}
@Override
public BytesStore bytesStore() {
return bytes;
}
@Override
public long offset() {
return offset;
}
@Override
public long maxSize() {
return length;
}
public String toString() {
if (bytes == null)
return "not set";
StringBuilder sb = new StringBuilder();
sb.append("used: ");
long used = getUsed();
sb.append(used);
sb.append(", value: ");
String sep = "";
try {
int i, max = (int) Math.min(used, Math.min(getCapacity(), MAX_TO_STRING));
for (i = 0; i < max; i++) {
long valueAt = getValueAt(i);
sb.append(sep).append(valueAt);
sep = ", ";
}
if (i < getCapacity())
sb.append(" ...");
} catch (BufferUnderflowException e) {
sb.append(" ").append(e);
}
return sb.toString();
}
@Override
public long sizeInBytes(long capacity) {
throwExceptionIfClosed();
return (capacity << SHIFT) + VALUES;
}
@Override
public ByteableLongArrayValues capacity(long arrayLength) {
throwExceptionIfClosedInSetter();
BytesStore bytesStore = bytesStore();
long length = sizeInBytes(arrayLength);
if (bytesStore == null) {
this.length = length;
} else {
assert this.length == length;
}
return this;
}
@Override
public boolean compareAndSet(long index, long expected, long value) throws IllegalArgumentException, BufferOverflowException {
throwExceptionIfClosed();
if (value == LONG_NOT_COMPLETE && binaryLongArrayReferences != null)
binaryLongArrayReferences.add(new WeakReference<>(this));
return bytes.compareAndSwapLong(VALUES + offset + (index << SHIFT), expected, value);
}
}

@ -1,136 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import net.openhft.chronicle.bytes.BytesStore;
import org.jetbrains.annotations.NotNull;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
public class BinaryLongReference extends AbstractReference implements LongReference {
public static final long LONG_NOT_COMPLETE = -1;
@SuppressWarnings("rawtypes")
@Override
public void bytesStore( final BytesStore bytes, final long offset, final long length) throws IllegalStateException, IllegalArgumentException, BufferOverflowException, BufferUnderflowException {
throwExceptionIfClosed();
if (length != maxSize())
throw new IllegalArgumentException();
super.bytesStore(bytes, offset, length);
}
@Override
public long maxSize() {
return 8;
}
public String toString() {
return bytes == null ? "bytes is null" : "value: " + getValue();
}
@Override
public long getValue() {
return bytes == null ? 0L : bytes.readLong(offset);
}
@Override
public void setValue(long value) {
try {
bytes.writeLong(offset, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long getVolatileValue() {
try {
return bytes.readVolatileLong(offset);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public void setVolatileValue(long value) {
try {
bytes.writeVolatileLong(offset, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long getVolatileValue(long closedValue) {
if (isClosed())
return closedValue;
try {
return getVolatileValue();
} catch (Exception e) {
return closedValue;
}
}
@Override
public void setOrderedValue(long value) {
try {
bytes.writeOrderedLong(offset, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long addValue(long delta) {
try {
return bytes.addAndGetLong(offset, delta);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long addAtomicValue(long delta) {
return addValue(delta);
}
@Override
public boolean compareAndSwapValue(long expected, long value) {
try {
return bytes.compareAndSwapLong(offset, expected, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
}

@ -1,113 +0,0 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.bytes.ref;
import org.jetbrains.annotations.NotNull;
public class BinaryTwoLongReference extends BinaryLongReference implements TwoLongReference {
@Override
public long maxSize() {
return 2 * 8;
}
public String toString() {
return bytes == null ? "bytes is null" : "value: " + getValue() + ", value2: " + getValue2();
}
@Override
public long getValue2() {
try {
return bytes.readLong(offset + 8);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public void setValue2(long value) {
try {
bytes.writeLong(offset + 8, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long getVolatileValue2() {
try {
return bytes.readVolatileLong(offset + 8);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public void setVolatileValue2(long value) {
try {
bytes.writeVolatileLong(offset + 8, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public void setOrderedValue2(long value) {
try {
bytes.writeOrderedLong(offset + 8, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long addValue2(long delta) {
try {
return bytes.addAndGetLong(offset + 8, delta);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public long addAtomicValue2(long delta) {
try {
return addValue2(delta);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
@Override
public boolean compareAndSwapValue2(long expected, long value) {
try {
return bytes.compareAndSwapLong(offset + 8, expected, value);
} catch (NullPointerException e) {
throwExceptionIfClosed();
throw e;
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save