diff --git a/src/main/java/net/openhft/chronicle/hash/Data.java b/src/main/java/net/openhft/chronicle/hash/Data.java index 49a3b7e17..61ee44b4e 100644 --- a/src/main/java/net/openhft/chronicle/hash/Data.java +++ b/src/main/java/net/openhft/chronicle/hash/Data.java @@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Objects; import static net.openhft.chronicle.algo.bytes.Access.checkedRandomDataInputAccess; @@ -137,7 +138,7 @@ public interface Data { * @param targetOffset the offset in the target, to write the bytes from. */ default void writeTo(RandomDataOutput target, long targetOffset) { - target.write(targetOffset, bytes(), offset(), size()); + target.write(targetOffset, Objects.requireNonNull(bytes()), offset(), size()); } /** diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index d71fa4148..0b5a99d75 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -750,6 +750,7 @@ public final class ChronicleMapBuilder implements double valueSize = averageValueSize(); size += averageSizeStoringLength(valueBuilder, valueSize); int alignment = valueAlignment(); + size = alignAddr((long) Math.ceil(size), alignment); // so the value starts aligned int worstAlignment; if (worstAlignmentComputationRequiresValueSize(alignment)) { long constantSizeBeforeAlignment = toLong(size); @@ -925,6 +926,8 @@ public final class ChronicleMapBuilder implements throw new IllegalArgumentException("Alignment should be a power of 2, " + alignment + " given"); } + if (Jvm.isArm() && alignment < 8) + return this; this.alignment = alignment; return this; } diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java old mode 100644 new mode 100755 index 66e48eeb9..71c7b7eaa --- a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java @@ -23,7 +23,6 @@ import net.openhft.chronicle.core.OS; import org.jetbrains.annotations.Nullable; import java.nio.BufferOverflowException; -import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; public enum ZeroBytesStore implements BytesStore { @@ -40,22 +39,22 @@ public enum ZeroBytesStore implements BytesStore { } @Override - public byte readVolatileByte(long offset) throws BufferUnderflowException { + public byte readVolatileByte(long offset) { return 0; } @Override - public short readVolatileShort(long offset) throws BufferUnderflowException { + public short readVolatileShort(long offset) { return 0; } @Override - public int readVolatileInt(long offset) throws BufferUnderflowException { + public int readVolatileInt(long offset) { return 0; } @Override - public long readVolatileLong(long offset) throws BufferUnderflowException { + public long readVolatileLong(long offset) { return 0; } @@ -128,22 +127,31 @@ public enum ZeroBytesStore implements BytesStore { } @Override - public long addressForRead(long offset) throws UnsupportedOperationException { + public long addressForRead(long offset) { return offset; } @Override - public boolean compareAndSwapInt(long offset, int expected, int value) - throws BufferOverflowException, IllegalArgumentException { - throw new UnsupportedOperationException(); + public boolean compareAndSwapInt(long offset, int expected, int value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); + return true; } @Override - public boolean compareAndSwapLong(long offset, long expected, long value) - throws BufferOverflowException, IllegalArgumentException { - throw new UnsupportedOperationException(); + public void testAndSetInt(long offset, int expected, int value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); } + @Override + public boolean compareAndSwapLong(long offset, long expected, long value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); + return true; + } + + @Override public void reserve() throws IllegalStateException { } diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java index 7cf378b91..36cd80a95 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/entry/MapEntryStages.java @@ -224,21 +224,16 @@ public abstract class MapEntryStages extends HashEntryStages } public long innerEntrySize(long sizeOfEverythingBeforeValue, long valueSize) { - long sizeWithoutChecksum; - if (mh.m().constantlySizedEntry) { - sizeWithoutChecksum = - alignAddr(sizeOfEverythingBeforeValue + valueSize, mh.m().alignment); - } else if (mh.m().couldNotDetermineAlignmentBeforeAllocation) { - sizeWithoutChecksum = sizeOfEverythingBeforeValue + mh.m().worstAlignment + valueSize; - } else { - sizeWithoutChecksum = - alignAddr(sizeOfEverythingBeforeValue, mh.m().alignment) + valueSize; - } - return sizeWithoutChecksum + checksumStrategy.extraEntryBytes(); + if (!mh.m().constantlySizedEntry && mh.m().couldNotDetermineAlignmentBeforeAllocation) + sizeOfEverythingBeforeValue += mh.m().worstAlignment; + int alignment = mh.m().alignment; + return alignAddr(sizeOfEverythingBeforeValue, alignment) + + alignAddr(valueSize, alignment); } long sizeOfEverythingBeforeValue(long keySize, long valueSize) { return mh.m().keySizeMarshaller.storingLength(keySize) + keySize + + checksumStrategy.extraEntryBytes() + mh.m().valueSizeMarshaller.storingLength(valueSize); } diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java index 761a3fd16..75d4560b6 100755 --- a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java @@ -619,7 +619,7 @@ public class ChronicleMapTest { .entries((long) entries) .minSegments(1) .averageKeySize(10) - .entryAndValueOffsetAlignment(4) + .entryAndValueOffsetAlignment(8) .create()) { LongValue value4 = Values.newNativeReference(LongValue.class); LongValue value22 = Values.newNativeReference(LongValue.class); @@ -651,9 +651,9 @@ public class ChronicleMapTest { try (ChronicleMap map1 = ChronicleMapBuilder.of(CharSequence.class, LongValue.class) .entries((long) entries) - .minSegments(1) +// .minSegments(1) .averageKeySize(10) - .entryAndValueOffsetAlignment(1) +// .entryAndValueOffsetAlignment(8) .create()) { LongValue value1 = Values.newNativeReference(LongValue.class); LongValue value21 = Values.newNativeReference(LongValue.class); diff --git a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java index 6fca59a77..2277c4d77 100755 --- a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java @@ -56,6 +56,7 @@ public class DemoChronicleMapTest { .putReturnsNull(true) .removeReturnsNull(true) .entries(maxEntries) + .entryAndValueOffsetAlignment(8) .createPersistedTo(file)) { IntValue key = Values.newHeapInstance(IntValue.class); @@ -98,6 +99,7 @@ public class DemoChronicleMapTest { .putReturnsNull(true) .removeReturnsNull(true) .entries(maxEntries) + .entryAndValueOffsetAlignment(8) .createPersistedTo(file)) { IntValue key = Values.newHeapInstance(IntValue.class); diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java index 32e3e8fde..1d0aca340 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java @@ -23,6 +23,7 @@ import net.openhft.chronicle.map.ExternalMapQueryContext; import net.openhft.chronicle.values.Values; import org.junit.Test; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.text.ParseException; @@ -99,8 +100,7 @@ public class OpenJDKAndHashMapExamplesTest { BondVOInterface bond = Values.newNativeReference(BondVOInterface.class); // lookup the key and give me a reference I can update in a thread safe way. - try (net.openhft.chronicle.core.io.Closeable c = - chm.acquireContext("369604103", bond)) { + try (Closeable c = chm.acquireContext("369604103", bond)) { // found a key and bond has been set // get directly without touching the rest of the record. long _matDate = bond.getMaturityDate();