blob: a211db6c843b1def8d13445242a0ed23139c2556 [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.
*/
/*
* Note: Lincoln's Gettysburg Address is in the public domain. See LICENSE.
*/
package org.apache.datasketches.memory.internal;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import org.apache.datasketches.memory.DefaultMemoryRequestServer;
import org.apache.datasketches.memory.Memory;
import org.apache.datasketches.memory.MemoryRequestServer;
import org.apache.datasketches.memory.Resource;
import org.apache.datasketches.memory.WritableBuffer;
import org.apache.datasketches.memory.WritableMemory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.collections.Lists;
public class MemoryTest {
private static final String LS = Util.LS;
@BeforeClass
public void setReadOnly() {
UtilTest.setGettysburgAddressFileToReadOnly();
}
@Test
public void checkDirectRoundTrip() throws Exception {
int n = 1024; //longs
try (WritableMemory mem = WritableMemory.allocateDirect(n * 8)) {
for (int i = 0; i < n; i++) {
mem.putLong(i * 8, i);
}
for (int i = 0; i < n; i++) {
long v = mem.getLong(i * 8);
assertEquals(v, i);
}
}
}
@Test
public void checkAutoHeapRoundTrip() {
int n = 1024; //longs
WritableMemory wmem = WritableMemory.allocate(n * 8);
for (int i = 0; i < n; i++) {
wmem.putLong(i * 8, i);
}
for (int i = 0; i < n; i++) {
long v = wmem.getLong(i * 8);
assertEquals(v, i);
}
}
@Test
public void checkArrayWrap() {
int n = 1024; //longs
byte[] arr = new byte[n * 8];
WritableMemory wmem = WritableMemory.writableWrap(arr);
for (int i = 0; i < n; i++) {
wmem.putLong(i * 8, i);
}
for (int i = 0; i < n; i++) {
long v = wmem.getLong(i * 8);
assertEquals(v, i);
}
Memory mem = Memory.wrap(arr, ByteOrder.nativeOrder());
for (int i = 0; i < n; i++) {
long v = mem.getLong(i * 8);
assertEquals(v, i);
}
// check 0 length array wraps
Memory memZeroLengthArrayBoolean = WritableMemory.writableWrap(new boolean[0]);
Memory memZeroLengthArrayByte = WritableMemory.writableWrap(new byte[0]);
Memory memZeroLengthArrayChar = WritableMemory.writableWrap(new char[0]);
Memory memZeroLengthArrayShort = WritableMemory.writableWrap(new short[0]);
Memory memZeroLengthArrayInt = WritableMemory.writableWrap(new int[0]);
Memory memZeroLengthArrayLong = WritableMemory.writableWrap(new long[0]);
Memory memZeroLengthArrayFloat = WritableMemory.writableWrap(new float[0]);
Memory memZeroLengthArrayDouble = WritableMemory.writableWrap(new double[0]);
assertEquals(memZeroLengthArrayBoolean.getCapacity(), 0);
assertEquals(memZeroLengthArrayByte.getCapacity(), 0);
assertEquals(memZeroLengthArrayChar.getCapacity(), 0);
assertEquals(memZeroLengthArrayShort.getCapacity(), 0);
assertEquals(memZeroLengthArrayInt.getCapacity(), 0);
assertEquals(memZeroLengthArrayLong.getCapacity(), 0);
assertEquals(memZeroLengthArrayFloat.getCapacity(), 0);
assertEquals(memZeroLengthArrayDouble.getCapacity(), 0);
// check 0 length array wraps
List<Memory> memoryToCheck = Lists.newArrayList();
memoryToCheck.add(WritableMemory.allocate(0));
memoryToCheck.add(WritableMemory.writableWrap(ByteBuffer.allocate(0)));
memoryToCheck.add(WritableMemory.writableWrap(new boolean[0]));
memoryToCheck.add(WritableMemory.writableWrap(new byte[0]));
memoryToCheck.add(WritableMemory.writableWrap(new char[0]));
memoryToCheck.add(WritableMemory.writableWrap(new short[0]));
memoryToCheck.add(WritableMemory.writableWrap(new int[0]));
memoryToCheck.add(WritableMemory.writableWrap(new long[0]));
memoryToCheck.add(WritableMemory.writableWrap(new float[0]));
memoryToCheck.add(WritableMemory.writableWrap(new double[0]));
memoryToCheck.add(Memory.wrap(ByteBuffer.allocate(0)));
memoryToCheck.add(Memory.wrap(new boolean[0]));
memoryToCheck.add(Memory.wrap(new byte[0]));
memoryToCheck.add(Memory.wrap(new char[0]));
memoryToCheck.add(Memory.wrap(new short[0]));
memoryToCheck.add(Memory.wrap(new int[0]));
memoryToCheck.add(Memory.wrap(new long[0]));
memoryToCheck.add(Memory.wrap(new float[0]));
memoryToCheck.add(Memory.wrap(new double[0]));
//Check the Memory lengths
for (Memory memory : memoryToCheck) {
assertEquals(memory.getCapacity(), 0);
}
}
@Test
public void checkByteBufHeap() {
int n = 1024; //longs
byte[] arr = new byte[n * 8];
ByteBuffer bb = ByteBuffer.wrap(arr);
bb.order(ByteOrder.nativeOrder());
WritableMemory wmem = WritableMemory.writableWrap(bb);
for (int i = 0; i < n; i++) { //write to wmem
wmem.putLong(i * 8, i);
}
for (int i = 0; i < n; i++) { //read from wmem
long v = wmem.getLong(i * 8);
assertEquals(v, i);
}
for (int i = 0; i < n; i++) { //read from BB
long v = bb.getLong(i * 8);
assertEquals(v, i);
}
Memory mem1 = Memory.wrap(arr);
for (int i = 0; i < n; i++) { //read from wrapped arr
long v = mem1.getLong(i * 8);
assertEquals(v, i);
}
//convert to RO
Memory mem = wmem;
for (int i = 0; i < n; i++) {
long v = mem.getLong(i * 8);
assertEquals(v, i);
}
}
@Test
public void checkByteBufDirect() {
int n = 1024; //longs
ByteBuffer bb = ByteBuffer.allocateDirect(n * 8);
bb.order(ByteOrder.nativeOrder());
WritableMemory wmem = WritableMemory.writableWrap(bb);
for (int i = 0; i < n; i++) { //write to wmem
wmem.putLong(i * 8, i);
}
for (int i = 0; i < n; i++) { //read from wmem
long v = wmem.getLong(i * 8);
assertEquals(v, i);
}
for (int i = 0; i < n; i++) { //read from BB
long v = bb.getLong(i * 8);
assertEquals(v, i);
}
Memory mem1 = Memory.wrap(bb);
for (int i = 0; i < n; i++) { //read from wrapped bb RO
long v = mem1.getLong(i * 8);
assertEquals(v, i);
}
//convert to RO
Memory mem = wmem;
for (int i = 0; i < n; i++) {
long v = mem.getLong(i * 8);
assertEquals(v, i);
}
}
@Test
public void checkByteBufWrongOrder() {
int n = 1024; //longs
ByteBuffer bb = ByteBuffer.allocate(n * 8);
bb.order(ByteOrder.BIG_ENDIAN);
Memory mem = Memory.wrap(bb);
assertFalse(mem.getByteOrder() == ByteOrder.nativeOrder());
assertEquals(mem.getByteOrder(), ByteOrder.BIG_ENDIAN);
}
@Test
public void checkReadOnlyHeapByteBuffer() {
ByteBuffer bb = ByteBuffer.allocate(128);
bb.order(ByteOrder.nativeOrder());
for (int i = 0; i < 128; i++) { bb.put(i, (byte)i); }
bb.position(64);
ByteBuffer slice = bb.slice().asReadOnlyBuffer();
slice.order(ByteOrder.nativeOrder());
Memory mem = Memory.wrap(slice);
for (int i = 0; i < 64; i++) {
assertEquals(mem.getByte(i), 64 + i);
}
mem.toHexString("slice", 0, slice.capacity());
//println(s);
}
@Test
public void checkPutGetArraysHeap() {
int n = 1024; //longs
long[] arr = new long[n];
for (int i = 0; i < n; i++) { arr[i] = i; }
WritableMemory wmem = WritableMemory.allocate(n * 8);
wmem.putLongArray(0, arr, 0, n);
long[] arr2 = new long[n];
wmem.getLongArray(0, arr2, 0, n);
for (int i = 0; i < n; i++) {
assertEquals(arr2[i], i);
}
}
@Test
public void checkRORegions() {
int n = 16;
int n2 = n / 2;
long[] arr = new long[n];
for (int i = 0; i < n; i++) { arr[i] = i; }
Memory mem = Memory.wrap(arr);
Memory reg = mem.region(n2 * 8, n2 * 8); //top half
for (int i = 0; i < n2; i++) {
long v = reg.getLong(i * 8);
long e = i + n2;
assertEquals(v, e);
}
}
@Test
public void checkRORegionsReverseBO() {
int n = 16;
int n2 = n / 2;
long[] arr = new long[n];
for (int i = 0; i < n; i++) { arr[i] = i; }
Memory mem = Memory.wrap(arr);
Memory reg = mem.region(n2 * 8, n2 * 8, Util.NON_NATIVE_BYTE_ORDER); //top half
for (int i = 0; i < n2; i++) {
long v = Long.reverseBytes(reg.getLong(i * 8));
long e = i + n2;
assertEquals(v, e);
}
}
@Test
public void checkWRegions() {
int n = 16;
int n2 = n / 2;
long[] arr = new long[n];
for (int i = 0; i < n; i++) { arr[i] = i; }
WritableMemory wmem = WritableMemory.writableWrap(arr);
for (int i = 0; i < n; i++) {
assertEquals(wmem.getLong(i * 8), i);
//println("" + wmem.getLong(i * 8));
}
//println("");
WritableMemory reg = wmem.writableRegion(n2 * 8, n2 * 8);
for (int i = 0; i < n2; i++) { reg.putLong(i * 8, i); }
for (int i = 0; i < n; i++) {
assertEquals(wmem.getLong(i * 8), i % 8);
//println("" + wmem.getLong(i * 8));
}
}
@Test
public void checkWRegionsReverseBO() {
int n = 16;
int n2 = n / 2;
long[] arr = new long[n];
for (int i = 0; i < n; i++) { arr[i] = i; }
WritableMemory wmem = WritableMemory.writableWrap(arr);
for (int i = 0; i < n; i++) {
assertEquals(wmem.getLong(i * 8), i);
//println("" + wmem.getLong(i * 8));
}
//println("");
WritableMemory reg = wmem.writableRegion(n2 * 8, n2 * 8, Util.NON_NATIVE_BYTE_ORDER);
for (int i = 0; i < n2; i++) { reg.putLong(i * 8, i); }
for (int i = 0; i < n; i++) {
long v = wmem.getLong(i * 8);
if (i < n2) {
assertEquals(v, i % 8);
} else {
assertEquals(Long.reverseBytes(v), i % 8);
}
//println("" + wmem.getLong(i * 8));
}
}
@Test(expectedExceptions = IllegalStateException.class)
public void checkParentUseAfterFree() throws Exception {
int bytes = 64 * 8;
WritableMemory wmem = WritableMemory.allocateDirect(bytes);
wmem.close();
wmem.getLong(0);
}
@Test(expectedExceptions = IllegalStateException.class)
public void checkRegionUseAfterFree() throws Exception {
int bytes = 64;
Memory mem = WritableMemory.allocateDirect(bytes);
Memory region = mem.region(0L, bytes);
mem.close();
region.getByte(0);
}
@Test
public void checkMemReqSvr() throws Exception {
WritableMemory wmem;
WritableBuffer wbuf;
if (Resource.defaultMemReqSvr == null) { //This is a policy choice
//ON HEAP
wmem = WritableMemory.writableWrap(new byte[16]);
assertNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
//OFF HEAP
try (WritableMemory wmem2 = WritableMemory.allocateDirect(16)) { //OFF HEAP
assertNull(wmem2.getMemoryRequestServer());
wbuf = wmem2.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
}
//ByteBuffer
ByteBuffer bb = ByteBuffer.allocate(16);
wmem = WritableMemory.writableWrap(bb);
assertNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNull(wbuf.getMemoryRequestServer());
}
MemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
//ON HEAP
wmem = WritableMemory.writableWrap(new byte[16], 0, 16, Util.NATIVE_BYTE_ORDER, memReqSvr);
assertNotNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNotNull(wbuf.getMemoryRequestServer());
//OFF HEAP
try (WritableMemory wmem3 = WritableMemory.allocateDirect(16, Util.NATIVE_BYTE_ORDER, memReqSvr)) {
assertNotNull(wmem3.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNotNull(wbuf.getMemoryRequestServer());
}
//ByteBuffer
ByteBuffer bb = ByteBuffer.allocate(16);
wmem = WritableMemory.writableWrap(bb, Util.NATIVE_BYTE_ORDER, memReqSvr);
assertNotNull(wmem.getMemoryRequestServer());
wbuf = wmem.asWritableBuffer();
assertNotNull(wbuf.getMemoryRequestServer());
}
@Test
public void checkSelfEqualsToAndCompareTo() {
int len = 64;
WritableMemory wmem = WritableMemory.allocate(len);
for (int i = 0; i < len; i++) { wmem.putByte(i, (byte) i); }
assertTrue(wmem.equalTo(0, wmem, 0, len));
assertFalse(wmem.equalTo(0, wmem, len / 2, len / 2));
assertEquals(wmem.compareTo(0, len, wmem, 0, len), 0);
assertTrue(wmem.compareTo(0, 0, wmem, len / 2, len / 2) < 0);
}
@Test
public void wrapBigEndianAsLittle() {
ByteBuffer bb = ByteBuffer.allocate(64);
bb.putChar(0, (char)1); //as NNO
Memory mem = Memory.wrap(bb, ByteOrder.LITTLE_ENDIAN);
assertEquals(mem.getChar(0), 256);
}
@Test
public void checkIssue178() {
int n = 8;
byte[] bArr = new byte[n];
for (int i = 0; i < n; i++) { bArr[i] = (byte)i; }
Memory mem = Memory.wrap(bArr, n / 2, n / 2, ByteOrder.nativeOrder());
for (int i = 0; i < n / 2; i++) {
println(mem.getByte(i));
assertEquals(mem.getByte(i), n / 2 + i);
}
}
@Test
public void printlnTest() {
println("PRINTING: " + this.getClass().getName());
}
static void println(final Object o) {
if (o == null) { print(LS); }
else { print(o.toString() + LS); }
}
/**
* @param o value to print
*/
static void print(final Object o) {
if (o != null) {
//System.out.print(o.toString()); //disable here
}
}
}