blob: 7cefd14e6c7f20242746b09c27b2a0136233cf5a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.datasketches.memory;
import static org.apache.datasketches.memory.CompareAndCopy.UNSAFE_COPY_THRESHOLD_BYTES;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.ThreadLocalRandom;
import org.testng.annotations.Test;
public class WritableMemoryTest {
@Test
public void wrapBigEndian() {
ByteBuffer bb = ByteBuffer.allocate(64); //big endian
WritableMemory wmem = WritableMemory.wrap(bb);
assertEquals(wmem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
public void wrapBigEndian2() {
ByteBuffer bb = ByteBuffer.allocate(64);
WritableBuffer wbuf = WritableBuffer.wrap(bb);
assertFalse(wbuf.getTypeByteOrder() == BaseState.nativeByteOrder);
assertEquals(wbuf.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
public void wrapBigEndianAsLittle() {
ByteBuffer bb = ByteBuffer.allocate(64);
bb.putChar(0, (char)1); //as BE
WritableMemory wmem = WritableMemory.wrap(bb, ByteOrder.LITTLE_ENDIAN);
assertEquals(wmem.getChar(0), 256);
}
@Test
public void allocateWithByteOrder() {
WritableMemory wmem = WritableMemory.allocate(64, ByteOrder.BIG_ENDIAN);
assertEquals(wmem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
wmem = WritableMemory.allocate(64, ByteOrder.LITTLE_ENDIAN);
assertEquals(wmem.getTypeByteOrder(), ByteOrder.LITTLE_ENDIAN);
}
@Test
public void checkGetArray() {
byte[] byteArr = new byte[64];
WritableMemory wmem = WritableMemory.wrap(byteArr);
assertTrue(wmem.getArray() == byteArr);
WritableBuffer wbuf = wmem.asWritableBuffer();
assertTrue(wbuf.getArray() == byteArr);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void checkSelfArrayCopy() {
byte[] srcAndDst = new byte[128];
WritableMemory wmem = WritableMemory.wrap(srcAndDst);
wmem.getByteArray(0, srcAndDst, 64, 64); //non-overlapping
}
@Test
public void checkEquals() {
int len = 7;
WritableMemory wmem1 = WritableMemory.allocate(len);
//@SuppressWarnings({"EqualsWithItself", "SelfEquals"}) //unsupported
//SelfEquals for Plexus, EqualsWithItself for IntelliJ
//boolean eq1 = wmem1.equals(wmem1); //strict profile complains
//assertTrue(eq1);
WritableMemory wmem2 = WritableMemory.allocate(len + 1);
assertFalse(wmem1.equals(wmem2));
WritableMemory reg1 = wmem1.writableRegion(0, wmem1.getCapacity());
assertTrue(wmem1.equals(reg1));
wmem2 = WritableMemory.allocate(len);
for (int i = 0; i < len; i++) {
wmem1.putByte(i, (byte) i);
wmem2.putByte(i, (byte) i);
}
assertTrue(wmem1.equals(wmem2));
assertTrue(wmem1.equalTo(0, wmem1, 0, len));
reg1 = wmem1.writableRegion(0, wmem1.getCapacity());
assertTrue(wmem1.equalTo(0, reg1, 0, len));
len = 24;
wmem1 = WritableMemory.allocate(len);
wmem2 = WritableMemory.allocate(len);
for (int i = 0; i < len; i++) {
wmem1.putByte(i, (byte) i);
wmem2.putByte(i, (byte) i);
}
assertTrue(wmem1.equalTo(0, wmem2, 0, len - 1));
assertTrue(wmem1.equalTo(0, wmem2, 0, len));
wmem2.putByte(0, (byte) 10);
assertFalse(wmem1.equalTo(0, wmem2, 0, len));
wmem2.putByte(0, (byte) 0);
wmem2.putByte(len - 2, (byte) 0);
assertFalse(wmem1.equalTo(0, wmem2, 0, len - 1));
}
@Test
public void checkEquals2() {
int len = 23;
WritableMemory wmem1 = WritableMemory.allocate(len);
assertFalse(wmem1.equals(null));
//@SuppressWarnings({"EqualsWithItself", "SelfEquals"}) //unsupported
//SelfEquals for Plexus, EqualsWithItself for IntelliJ
//boolean eq1 = wmem1.equals(wmem1); //strict profile complains
//assertTrue(eq1);
WritableMemory wmem2 = WritableMemory.allocate(len + 1);
assertFalse(wmem1.equals(wmem2));
for (int i = 0; i < len; i++) {
wmem1.putByte(i, (byte) i);
wmem2.putByte(i, (byte) i);
}
assertTrue(wmem1.equalTo(0, wmem2, 0, len));
assertTrue(wmem1.equalTo(1, wmem2, 1, len - 1));
}
@Test
public void checkLargeEquals() {
// Size bigger than UNSAFE_COPY_MEMORY_THRESHOLD; size with "reminder" = 7, to test several
// traits of the implementation
final int thresh = UNSAFE_COPY_THRESHOLD_BYTES;
byte[] bytes1 = new byte[(thresh * 2) + 7];
ThreadLocalRandom.current().nextBytes(bytes1);
byte[] bytes2 = bytes1.clone();
Memory mem1 = Memory.wrap(bytes1);
Memory mem2 = Memory.wrap(bytes2);
assertTrue(mem1.equals(mem2));
bytes2[thresh + 10] = (byte) (bytes1[thresh + 10] + 1);
assertFalse(mem1.equals(mem2));
bytes2[thresh + 10] = bytes1[thresh + 10];
bytes2[(thresh * 2) + 3] = (byte) (bytes1[(thresh * 2) + 3] + 1);
assertFalse(mem1.equals(mem2));
}
@Test
public void checkWrapWithBO() {
WritableMemory wmem = WritableMemory.wrap(new byte[0], ByteOrder.BIG_ENDIAN);
boolean nativeBO = wmem.getTypeByteOrder() == BaseState.nativeByteOrder;
assertTrue(nativeBO); //remains true for ZeroSizeMemory
println("" + nativeBO);
wmem = WritableMemory.wrap(new byte[8], ByteOrder.BIG_ENDIAN);
nativeBO = wmem.getTypeByteOrder() == BaseState.nativeByteOrder;
assertFalse(nativeBO);
println("" + nativeBO);
}
@Test
@SuppressWarnings("unused")
public void checkOwnerClientCase() {
WritableMemory owner = WritableMemory.allocate(64);
Memory client1 = owner; //Client1 cannot write (no API)
owner.putInt(0, 1); //But owner can write
((WritableMemory)client1).putInt(0, 2); //Client1 can write, but with explicit effort.
Memory client2 = owner.region(0, owner.getCapacity()); //client2 cannot write (no API)
owner.putInt(0, 3); //But Owner should be able to write
}
@Test
public void printlnTest() {
println("PRINTING: "+this.getClass().getName());
}
/**
* @param s value to print
*/
static void println(final String s) {
//System.out.println(s);
}
}