http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectJUnitTest.java new file mode 100644 index 0000000..2f6b32c --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectJUnitTest.java @@ -0,0 +1,869 @@ +/* + * 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 com.gemstone.gemfire.internal.offheap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.LogWriter; +import com.gemstone.gemfire.compression.Compressor; +import com.gemstone.gemfire.internal.DSCODE; +import com.gemstone.gemfire.internal.HeapDataOutputStream; +import com.gemstone.gemfire.internal.Version; +import com.gemstone.gemfire.internal.cache.BytesAndBitsForCompactor; +import com.gemstone.gemfire.internal.cache.CachePerfStats; +import com.gemstone.gemfire.internal.cache.EntryEventImpl; +import com.gemstone.gemfire.internal.cache.RegionEntryContext; +import com.gemstone.gemfire.internal.offheap.MemoryBlock.State; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class OffHeapStoredObjectJUnitTest extends AbstractStoredObjectTestBase { + + private MemoryAllocator ma; + + static { + ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); + } + + @Before + public void setUp() { + OutOfOffHeapMemoryListener ooohml = mock(OutOfOffHeapMemoryListener.class); + OffHeapMemoryStats stats = mock(OffHeapMemoryStats.class); + LogWriter lw = mock(LogWriter.class); + + ma = SimpleMemoryAllocatorImpl.create(ooohml, stats, lw, 3, OffHeapStorage.MIN_SLAB_SIZE * 3, OffHeapStorage.MIN_SLAB_SIZE); + } + + @After + public void tearDown() { + SimpleMemoryAllocatorImpl.freeOffHeapMemory(); + } + + @Override + public Object getValue() { + return Long.valueOf(Long.MAX_VALUE); + } + + @Override + public byte[] getValueAsByteArray() { + return convertValueToByteArray(getValue()); + } + + private byte[] convertValueToByteArray(Object value) { + return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array(); + } + + @Override + public Object convertByteArrayToObject(byte[] valueInByteArray) { + return ByteBuffer.wrap(valueInByteArray).getLong(); + } + + @Override + public Object convertSerializedByteArrayToObject(byte[] valueInSerializedByteArray) { + return EntryEventImpl.deserialize(valueInSerializedByteArray); + } + + @Override + public OffHeapStoredObject createValueAsUnserializedStoredObject(Object value) { + byte[] valueInByteArray; + if (value instanceof Long) { + valueInByteArray = convertValueToByteArray(value); + } else { + valueInByteArray = (byte[]) value; + } + + boolean isSerialized = false; + boolean isCompressed = false; + + return createChunk(valueInByteArray, isSerialized, isCompressed); + } + + @Override + public OffHeapStoredObject createValueAsSerializedStoredObject(Object value) { + byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value); + + boolean isSerialized = true; + boolean isCompressed = false; + + return createChunk(valueInSerializedByteArray, isSerialized, isCompressed); + } + + private OffHeapStoredObject createChunk(byte[] v, boolean isSerialized, boolean isCompressed) { + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(v, isSerialized, isCompressed); + return chunk; + } + + @Test + public void chunkCanBeCreatedFromAnotherChunk() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + OffHeapStoredObject newChunk = new OffHeapStoredObject(chunk); + + assertNotNull(newChunk); + assertThat(newChunk.getAddress()).isEqualTo(chunk.getAddress()); + + chunk.release(); + } + + @Test + public void chunkCanBeCreatedWithOnlyMemoryAddress() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + OffHeapStoredObject newChunk = new OffHeapStoredObject(chunk.getAddress()); + + assertNotNull(newChunk); + assertThat(newChunk.getAddress()).isEqualTo(chunk.getAddress()); + + chunk.release(); + } + + @Test + public void chunkSliceCanBeCreatedFromAnotherChunk() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + int position = 1; + int end = 2; + + OffHeapStoredObject newChunk = (OffHeapStoredObject) chunk.slice(position, end); + + assertNotNull(newChunk); + assertThat(newChunk.getClass()).isEqualTo(OffHeapStoredObjectSlice.class); + assertThat(newChunk.getAddress()).isEqualTo(chunk.getAddress()); + + chunk.release(); + } + + @Test + public void fillSerializedValueShouldFillWrapperWithSerializedValueIfValueIsSerialized() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + // mock the things + BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class); + + byte userBits = 0; + byte serializedUserBits = 1; + chunk.fillSerializedValue(wrapper, userBits); + + verify(wrapper, times(1)).setOffHeapData(chunk, serializedUserBits); + + chunk.release(); + } + + @Test + public void fillSerializedValueShouldFillWrapperWithDeserializedValueIfValueIsNotSerialized() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + // mock the things + BytesAndBitsForCompactor wrapper = mock(BytesAndBitsForCompactor.class); + + byte userBits = 1; + chunk.fillSerializedValue(wrapper, userBits); + + verify(wrapper, times(1)).setOffHeapData(chunk, userBits); + + chunk.release(); + } + + @Test + public void getShortClassNameShouldReturnShortClassName() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getShortClassName()).isEqualTo("OffHeapStoredObject"); + + chunk.release(); + } + + @Test + public void chunksAreEqualsOnlyByAddress() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + OffHeapStoredObject newChunk = new OffHeapStoredObject(chunk.getAddress()); + assertThat(chunk.equals(newChunk)).isTrue(); + + OffHeapStoredObject chunkWithSameValue = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.equals(chunkWithSameValue)).isFalse(); + + Object someObject = getValue(); + assertThat(chunk.equals(someObject)).isFalse(); + + chunk.release(); + chunkWithSameValue.release(); + } + + @Test + public void chunksShouldBeComparedBySize() { + OffHeapStoredObject chunk1 = createValueAsSerializedStoredObject(getValue()); + + OffHeapStoredObject chunk2 = chunk1; + assertThat(chunk1.compareTo(chunk2)).isEqualTo(0); + + OffHeapStoredObject chunkWithSameValue = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk1.compareTo(chunkWithSameValue)).isEqualTo(Long.signum(chunk1.getAddress() - chunkWithSameValue.getAddress())); + + OffHeapStoredObject chunk3 = createValueAsSerializedStoredObject(Long.MAX_VALUE); + OffHeapStoredObject chunk4 = createValueAsSerializedStoredObject(Long.MAX_VALUE); + + int newSizeForChunk3 = 2; + int newSizeForChunk4 = 3; + + assertThat(chunk3.compareTo(chunk4)).isEqualTo(Integer.signum(newSizeForChunk3 - newSizeForChunk4)); + + chunk1.release(); + chunk4.release(); + } + + @Test + public void setSerializedShouldSetTheSerializedBit() { + Object regionEntryValue = getValue(); + byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue); + + boolean isSerialized = false; + boolean isCompressed = false; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed); + + int headerBeforeSerializedBitSet = AddressableMemoryManager.readIntVolatile(chunk.getAddress() + OffHeapStoredObject.REF_COUNT_OFFSET); + + assertThat(chunk.isSerialized()).isFalse(); + + chunk.setSerialized(true); // set to true + + assertThat(chunk.isSerialized()).isTrue(); + + int headerAfterSerializedBitSet = AddressableMemoryManager.readIntVolatile(chunk.getAddress() + OffHeapStoredObject.REF_COUNT_OFFSET); + + assertThat(headerAfterSerializedBitSet).isEqualTo(headerBeforeSerializedBitSet | OffHeapStoredObject.IS_SERIALIZED_BIT); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void setSerialziedShouldThrowExceptionIfChunkIsAlreadyReleased() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + chunk.setSerialized(true); + + chunk.release(); + } + + @Test + public void setCompressedShouldSetTheCompressedBit() { + Object regionEntryValue = getValue(); + byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue); + + boolean isSerialized = false; + boolean isCompressed = false; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed); + + int headerBeforeCompressedBitSet = AddressableMemoryManager.readIntVolatile(chunk.getAddress() + OffHeapStoredObject.REF_COUNT_OFFSET); + + assertThat(chunk.isCompressed()).isFalse(); + + chunk.setCompressed(true); // set to true + + assertThat(chunk.isCompressed()).isTrue(); + + int headerAfterCompressedBitSet = AddressableMemoryManager.readIntVolatile(chunk.getAddress() + OffHeapStoredObject.REF_COUNT_OFFSET); + + assertThat(headerAfterCompressedBitSet).isEqualTo(headerBeforeCompressedBitSet | OffHeapStoredObject.IS_COMPRESSED_BIT); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void setCompressedShouldThrowExceptionIfChunkIsAlreadyReleased() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + chunk.setCompressed(true); + + chunk.release(); + } + + @Test + public void setDataSizeShouldSetTheDataSizeBits() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + int beforeSize = chunk.getDataSize(); + + chunk.setDataSize(2); + + int afterSize = chunk.getDataSize(); + + assertThat(afterSize).isEqualTo(2); + assertThat(afterSize).isNotEqualTo(beforeSize); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void setDataSizeShouldThrowExceptionIfChunkIsAlreadyReleased() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + chunk.setDataSize(1); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyRetained() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.retain(); + chunk.initializeUseCount(); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void initializeUseCountShouldThrowIllegalStateExceptionIfChunkIsAlreadyReleased() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + chunk.initializeUseCount(); + + chunk.release(); + } + + @Test + public void isSerializedPdxInstanceShouldReturnTrueIfItsPDXInstance() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + byte[] serailizedValue = chunk.getSerializedValue(); + serailizedValue[0] = DSCODE.PDX; + chunk.setSerializedValue(serailizedValue); + + assertThat(chunk.isSerializedPdxInstance()).isTrue(); + + serailizedValue = chunk.getSerializedValue(); + serailizedValue[0] = DSCODE.PDX_ENUM; + chunk.setSerializedValue(serailizedValue); + + assertThat(chunk.isSerializedPdxInstance()).isTrue(); + + serailizedValue = chunk.getSerializedValue(); + serailizedValue[0] = DSCODE.PDX_INLINE_ENUM; + chunk.setSerializedValue(serailizedValue); + + assertThat(chunk.isSerializedPdxInstance()).isTrue(); + + chunk.release(); + } + + @Test + public void isSerializedPdxInstanceShouldReturnFalseIfItsNotPDXInstance() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk.isSerializedPdxInstance()).isFalse(); + + chunk.release(); + } + + @Test + public void checkDataEqualsByChunk() { + OffHeapStoredObject chunk1 = createValueAsSerializedStoredObject(getValue()); + OffHeapStoredObject sameAsChunk1 = chunk1; + + assertThat(chunk1.checkDataEquals(sameAsChunk1)).isTrue(); + + OffHeapStoredObject unserializedChunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk1.checkDataEquals(unserializedChunk)).isFalse(); + + OffHeapStoredObject chunkDifferBySize = createValueAsSerializedStoredObject(getValue()); + chunkDifferBySize.setSize(0); + assertThat(chunk1.checkDataEquals(chunkDifferBySize)).isFalse(); + + OffHeapStoredObject chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1); + assertThat(chunk1.checkDataEquals(chunkDifferByValue)).isFalse(); + + OffHeapStoredObject newChunk1 = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk1.checkDataEquals(newChunk1)).isTrue(); + + chunk1.release(); + unserializedChunk.release(); + chunkDifferBySize.release(); + chunkDifferByValue.release(); + newChunk1.release(); + } + + @Test + public void checkDataEqualsBySerializedValue() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk.checkDataEquals(new byte[1])).isFalse(); + + OffHeapStoredObject chunkDifferByValue = createValueAsSerializedStoredObject(Long.MAX_VALUE - 1); + assertThat(chunk.checkDataEquals(chunkDifferByValue.getSerializedValue())).isFalse(); + + OffHeapStoredObject newChunk = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk.checkDataEquals(newChunk.getSerializedValue())).isTrue(); + + chunk.release(); + chunkDifferByValue.release(); + newChunk.release(); + } + + @Test + public void getDecompressedBytesShouldReturnDecompressedBytesIfCompressed() { + Object regionEntryValue = getValue(); + byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue); + + boolean isSerialized = true; + boolean isCompressed = true; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed); + + RegionEntryContext regionContext = mock(RegionEntryContext.class); + CachePerfStats cacheStats = mock(CachePerfStats.class); + Compressor compressor = mock(Compressor.class); + + long startTime = 10000L; + + // mock required things + when(regionContext.getCompressor()).thenReturn(compressor); + when(compressor.decompress(regionEntryValueAsBytes)).thenReturn(regionEntryValueAsBytes); + when(regionContext.getCachePerfStats()).thenReturn(cacheStats); + when(cacheStats.startDecompression()).thenReturn(startTime); + + // invoke the thing + byte[] bytes = chunk.getDecompressedBytes(regionContext); + + // verify the thing happened + verify(cacheStats, atLeastOnce()).startDecompression(); + verify(compressor, times(1)).decompress(regionEntryValueAsBytes); + verify(cacheStats, atLeastOnce()).endDecompression(startTime); + + assertArrayEquals(regionEntryValueAsBytes, bytes); + + chunk.release(); + } + + @Test + public void incSizeShouldIncrementSize() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + int beforeSize = chunk.getSize(); + + chunk.incSize(1); + assertThat(chunk.getSize()).isEqualTo(beforeSize + 1); + + chunk.incSize(2); + assertThat(chunk.getSize()).isEqualTo(beforeSize + 1 + 2); + + chunk.release(); + } + + @Test + public void readyForFreeShouldResetTheRefCount() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + int refCountBeforeFreeing = chunk.getRefCount(); + assertThat(refCountBeforeFreeing).isEqualTo(1); + + chunk.readyForFree(); + + int refCountAfterFreeing = chunk.getRefCount(); + assertThat(refCountAfterFreeing).isEqualTo(0); + } + + @Test(expected = IllegalStateException.class) + public void readyForAllocationShouldThrowExceptionIfAlreadyAllocated() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + // chunk is already allocated when we created it, so calling readyForAllocation should throw exception. + chunk.readyForAllocation(); + + chunk.release(); + } + + @Test + public void checkIsAllocatedShouldReturnIfAllocated() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + chunk.checkIsAllocated(); + + chunk.release(); + } + + @Test(expected = IllegalStateException.class) + public void checkIsAllocatedShouldThrowExceptionIfNotAllocated() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + chunk.release(); + chunk.checkIsAllocated(); + + chunk.release(); + } + + @Test + public void sendToShouldWriteSerializedValueToDataOutputIfValueIsSerialized() throws IOException { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + OffHeapStoredObject spyChunk = spy(chunk); + + HeapDataOutputStream dataOutput = mock(HeapDataOutputStream.class); + ByteBuffer directByteBuffer = ByteBuffer.allocate(1024); + + doReturn(directByteBuffer).when(spyChunk).createDirectByteBuffer(); + doNothing().when(dataOutput).write(directByteBuffer); + + spyChunk.sendTo(dataOutput); + + verify(dataOutput, times(1)).write(directByteBuffer); + + chunk.release(); + } + + @Test + public void sendToShouldWriteUnserializedValueToDataOutputIfValueIsUnserialized() throws IOException { + byte[] regionEntryValue = getValueAsByteArray(); + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(regionEntryValue); + + // writeByte is a final method and cannot be mocked, so creating a real one + HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT); + + chunk.sendTo(dataOutput); + + byte[] actual = dataOutput.toByteArray(); + + byte[] expected = new byte[regionEntryValue.length + 2]; + expected[0] = DSCODE.BYTE_ARRAY; + expected[1] = (byte) regionEntryValue.length; + System.arraycopy(regionEntryValue, 0, expected, 2, regionEntryValue.length); + + assertNotNull(dataOutput); + assertThat(actual).isEqualTo(expected); + + chunk.release(); + } + + @Test + public void sendAsByteArrayShouldWriteValueToDataOutput() throws IOException { + byte[] regionEntryValue = getValueAsByteArray(); + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(regionEntryValue); + + // writeByte is a final method and cannot be mocked, so creating a real one + HeapDataOutputStream dataOutput = new HeapDataOutputStream(Version.CURRENT); + + chunk.sendAsByteArray(dataOutput); + + byte[] actual = dataOutput.toByteArray(); + + byte[] expected = new byte[regionEntryValue.length + 1]; + expected[0] = (byte) regionEntryValue.length; + System.arraycopy(regionEntryValue, 0, expected, 1, regionEntryValue.length); + + assertNotNull(dataOutput); + assertThat(actual).isEqualTo(expected); + + chunk.release(); + } + + @Test + public void createDirectByteBufferShouldCreateAByteBuffer() { + byte[] regionEntryValue = getValueAsByteArray(); + + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(regionEntryValue); + + ByteBuffer buffer = chunk.createDirectByteBuffer(); + + byte[] actual = new byte[regionEntryValue.length]; + buffer.get(actual); + + assertArrayEquals(regionEntryValue, actual); + + chunk.release(); + } + + @Test + public void getDirectByteBufferShouldCreateAByteBuffer() { + byte[] regionEntryValue = getValueAsByteArray(); + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(regionEntryValue); + + ByteBuffer buffer = chunk.createDirectByteBuffer(); + long bufferAddress = AddressableMemoryManager.getDirectByteBufferAddress(buffer); + + // returned address should be starting of the value (after skipping HEADER_SIZE bytes) + assertEquals(chunk.getAddress() + OffHeapStoredObject.HEADER_SIZE, bufferAddress); + + chunk.release(); + } + + @Test(expected = AssertionError.class) + public void getAddressForReadingDataShouldFailIfItsOutsideOfChunk() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + chunk.getAddressForReadingData(0, chunk.getDataSize() + 1); + + chunk.release(); + } + + @Test + public void getAddressForReadingDataShouldReturnDataAddressFromGivenOffset() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + int offset = 1; + long requestedAddress = chunk.getAddressForReadingData(offset, 1); + + assertThat(requestedAddress).isEqualTo(chunk.getBaseDataAddress() + offset); + + chunk.release(); + } + + @Test + public void getSizeInBytesShouldReturnSize() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + assertThat(chunk.getSizeInBytes()).isEqualTo(chunk.getSize()); + + chunk.release(); + } + + @Test(expected = AssertionError.class) + public void getAddressForReadingDataShouldFailIfOffsetIsNegative() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + chunk.getAddressForReadingData(-1, 1); + + chunk.release(); + } + + @Test(expected = AssertionError.class) + public void getAddressForReadingDataShouldFailIfSizeIsNegative() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + chunk.getAddressForReadingData(1, -1); + + chunk.release(); + } + + @Test(expected = AssertionError.class) + public void readByteAndWriteByteShouldFailIfOffsetIsOutside() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + chunk.readDataByte(chunk.getDataSize() + 1); + + chunk.writeDataByte(chunk.getDataSize() + 1, Byte.MAX_VALUE); + + chunk.release(); + } + + @Test + public void writeByteShouldWriteAtCorrectLocation() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + byte valueBeforeWrite = chunk.readDataByte(2); + + Byte expected = Byte.MAX_VALUE; + chunk.writeDataByte(2, expected); + + Byte actual = chunk.readDataByte(2); + + assertThat(actual).isNotEqualTo(valueBeforeWrite); + assertThat(actual).isEqualTo(expected); + + chunk.release(); + } + + @Test + public void retainShouldIncrementRefCount() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getRefCount()).isEqualTo(1); + + chunk.retain(); + assertThat(chunk.getRefCount()).isEqualTo(2); + + chunk.retain(); + assertThat(chunk.getRefCount()).isEqualTo(3); + + chunk.release(); + chunk.release(); + chunk.release(); + boolean retainAfterRelease = chunk.retain(); + + assertThat(retainAfterRelease).isFalse(); + } + + @Test(expected = IllegalStateException.class) + public void retainShouldThrowExceptionAfterMaxNumberOfTimesRetained() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + // loop though and invoke retain for MAX_REF_COUNT-1 times, as create chunk above counted as one reference + for (int i = 0; i < OffHeapStoredObject.MAX_REF_COUNT - 1; i++) + chunk.retain(); + + // invoke for the one more time should throw exception + chunk.retain(); + } + + @Test + public void releaseShouldDecrementRefCount() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getRefCount()).isEqualTo(1); + + chunk.retain(); + chunk.retain(); + assertThat(chunk.getRefCount()).isEqualTo(3); + + chunk.release(); + assertThat(chunk.getRefCount()).isEqualTo(2); + + chunk.release(); + assertThat(chunk.getRefCount()).isEqualTo(1); + + chunk.retain(); + chunk.release(); + assertThat(chunk.getRefCount()).isEqualTo(1); + + chunk.release(); + assertThat(chunk.getRefCount()).isEqualTo(0); + } + + @Test(expected = IllegalStateException.class) + public void releaseShouldThrowExceptionIfChunkIsAlreadyReleased() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + chunk.release(); + } + + @Test + public void testToString() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + String expected = ":<dataSize=" + chunk.getDataSize() + " refCount=" + chunk.getRefCount() + " addr=" + Long.toHexString(chunk.getAddress()) + ">"; + assertThat(chunk.toString()).endsWith(expected); + + chunk.release(); + } + + @Test + public void getStateShouldReturnAllocatedIfRefCountIsGreaterThanZero() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertEquals(State.ALLOCATED, chunk.getState()); + + chunk.release(); + } + + @Test + public void getStateShouldReturnDeallocatedIfRefCountIsZero() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.release(); + assertEquals(State.DEALLOCATED, chunk.getState()); + } + + @Test(expected = UnsupportedOperationException.class) + public void getNextBlockShouldThrowUnSupportedOperationException() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.getNextBlock(); + + chunk.release(); + } + + @Test + public void getBlockSizeShouldBeSameSameGetSize() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertEquals(chunk.getSize(), chunk.getBlockSize()); + + chunk.release(); + } + + @Test(expected = UnsupportedOperationException.class) + public void getSlabIdShouldThrowUnSupportedOperationException() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + chunk.getSlabId(); + + chunk.release(); + } + + @Test + public void getFreeListIdShouldReturnMinusOne() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getFreeListId()).isEqualTo(-1); + + chunk.release(); + } + + @Test + public void getDataTypeShouldReturnNull() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getDataType()).isNull(); + + chunk.release(); + } + + @Test + public void getDataDataShouldReturnNull() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + assertThat(chunk.getDataValue()).isNull(); + } + + @Test(expected = UnsupportedOperationException.class) + public void getRawBytesShouldThrowExceptionIfValueIsCompressed() { + Object regionEntryValue = getValue(); + byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue); + + boolean isSerialized = true; + boolean isCompressed = true; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed); + + chunk.getRawBytes(); + + chunk.release(); + } + + @Test + public void getSerializedValueShouldSerializeTheValue() { + Object regionEntryValue = getValue(); + byte[] regionEntryValueAsBytes = convertValueToByteArray(regionEntryValue); + + boolean isSerialized = false; + boolean isCompressed = false; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(regionEntryValueAsBytes, isSerialized, isCompressed); + + byte[] serializedValue = chunk.getSerializedValue(); + + assertThat(serializedValue).isEqualTo(EntryEventImpl.serialize(regionEntryValueAsBytes)); + + chunk.release(); + } + + @Test + public void fillShouldFillTheChunk() { + boolean isSerialized = false; + boolean isCompressed = false; + + OffHeapStoredObject chunk = (OffHeapStoredObject) ma.allocateAndInitialize(new byte[100], isSerialized, isCompressed); + + // first fill the unused part with FILL_PATTERN + OffHeapStoredObject.fill(chunk.getAddress()); + + // Validate that it is filled + chunk.validateFill(); + + chunk.release(); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectSliceJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectSliceJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectSliceJUnitTest.java new file mode 100644 index 0000000..1b5bf26 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectSliceJUnitTest.java @@ -0,0 +1,72 @@ +/* + * 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 com.gemstone.gemfire.internal.offheap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class OffHeapStoredObjectSliceJUnitTest extends OffHeapStoredObjectJUnitTest { + + @Test + public void sliceShouldHaveAValidDataSize() { + int position = 1; + int end = 2; + + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + OffHeapStoredObjectSlice slice = (OffHeapStoredObjectSlice) chunk.slice(position, end); + + assertNotNull(slice); + assertEquals(OffHeapStoredObjectSlice.class, slice.getClass()); + + assertEquals(end - position, slice.getDataSize()); + } + + @Test + public void sliceShouldHaveAValidBaseDataAddress() { + int position = 1; + int end = 2; + + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + OffHeapStoredObjectSlice slice = (OffHeapStoredObjectSlice) chunk.slice(position, end); + + assertNotNull(slice); + assertEquals(OffHeapStoredObjectSlice.class, slice.getClass()); + + assertEquals(chunk.getBaseDataAddress() + position, slice.getBaseDataAddress()); + } + + @Test + public void sliceShouldHaveAValidBaseOffset() { + int position = 1; + int end = 2; + + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + OffHeapStoredObjectSlice slice = (OffHeapStoredObjectSlice) chunk.slice(position, end); + + assertNotNull(slice); + assertEquals(OffHeapStoredObjectSlice.class, slice.getClass()); + + assertEquals(chunk.getBaseDataOffset() + position, slice.getBaseDataOffset()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectWithHeapFormJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectWithHeapFormJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectWithHeapFormJUnitTest.java new file mode 100644 index 0000000..a763e76 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStoredObjectWithHeapFormJUnitTest.java @@ -0,0 +1,64 @@ +/* + * 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 com.gemstone.gemfire.internal.offheap; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class OffHeapStoredObjectWithHeapFormJUnitTest extends OffHeapStoredObjectJUnitTest { + + @Test + public void getRawBytesShouldReturnCachedHeapForm() { + OffHeapStoredObject chunk = createValueAsUnserializedStoredObject(getValue()); + + byte[] valueInBytes = getValueAsByteArray(); + OffHeapStoredObjectWithHeapForm heapForm = new OffHeapStoredObjectWithHeapForm(chunk, valueInBytes); + + assertNotNull(heapForm); + + assertSame(valueInBytes, heapForm.getRawBytes()); + } + + @Test + public void getChunkWithoutHeapFormShouldReturnGemFireChunk() { + OffHeapStoredObject chunk = createValueAsSerializedStoredObject(getValue()); + + byte[] valueInBytes = getValueAsByteArray(); + OffHeapStoredObjectWithHeapForm heapForm = new OffHeapStoredObjectWithHeapForm(chunk, valueInBytes); + + OffHeapStoredObject chunkWithOutHeapForm = (OffHeapStoredObject)heapForm.getStoredObjectWithoutHeapForm(); + + assertNotNull(chunkWithOutHeapForm); + assertEquals(OffHeapStoredObject.class, chunkWithOutHeapForm.getClass()); + + assertEquals(chunk, heapForm.getStoredObjectWithoutHeapForm()); + + assertEquals(chunk.getAddress(), chunkWithOutHeapForm.getAddress()); + assertArrayEquals(chunk.getRawBytes(), chunkWithOutHeapForm.getRawBytes()); + assertNotSame(valueInBytes, chunkWithOutHeapForm.getRawBytes()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java index 630ae22..f8a5c8e 100755 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapValidationJUnitTest.java @@ -122,7 +122,7 @@ public class OffHeapValidationJUnitTest { assertEquals(1024*1024*2, firstBlock.getBlockSize()); assertEquals("N/A", firstBlock.getDataType()); assertEquals(-1, firstBlock.getFreeListId()); - assertTrue(firstBlock.getMemoryAddress() > 0); + assertTrue(firstBlock.getAddress() > 0); assertNull(firstBlock.getNextBlock()); assertEquals(0, firstBlock.getRefCount()); assertEquals(0, firstBlock.getSlabId()); @@ -202,7 +202,7 @@ public class OffHeapValidationJUnitTest { assertEquals(i + ":" + values.dataType, values.blockSize, block.getBlockSize()); assertEquals(i + ":" + values.dataType, values.dataType, block.getDataType()); assertEquals(i + ":" + values.dataType, values.freeListId, block.getFreeListId()); - assertEquals(i + ":" + values.dataType, values.memoryAddress, block.getMemoryAddress()); + assertEquals(i + ":" + values.dataType, values.memoryAddress, block.getAddress()); assertEquals(i + ":" + values.dataType, values.refCount, block.getRefCount()); assertEquals(i + ":" + values.dataType, values.slabId, block.getSlabId()); assertEquals(i + ":" + values.dataType, values.isCompressed, block.isCompressed()); @@ -296,8 +296,8 @@ public class OffHeapValidationJUnitTest { private long getMemoryAddress(Region region, String key) { Object entry = ((LocalRegion) region).getRegionEntry(key)._getValue(); - assertTrue(entry instanceof ObjectChunk); - long memoryAddress = ((ObjectChunk)entry).getMemoryAddress(); + assertTrue(entry instanceof OffHeapStoredObject); + long memoryAddress = ((OffHeapStoredObject)entry).getAddress(); assertTrue(memoryAddress > 0); return memoryAddress; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java index 9c83f5b..7157eaa 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapWriteObjectAsByteArrayJUnitTest.java @@ -35,7 +35,7 @@ import com.gemstone.gemfire.internal.offheap.NullOffHeapMemoryStats; import com.gemstone.gemfire.internal.offheap.NullOutOfOffHeapMemoryListener; import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl; import com.gemstone.gemfire.internal.offheap.StoredObject; -import com.gemstone.gemfire.internal.offheap.UnsafeMemoryChunk; +import com.gemstone.gemfire.internal.offheap.SlabImpl; import com.gemstone.gemfire.test.junit.categories.UnitTest; @Category(UnitTest.class) @@ -43,7 +43,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest { @Before public void setUp() throws Exception { - SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{new UnsafeMemoryChunk(1024*1024)}); + SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{new SlabImpl(1024*1024)}); } @After @@ -64,7 +64,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest { public void testByteArrayChunk() throws IOException, ClassNotFoundException { byte[] expected = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; StoredObject so = createStoredObject(expected, false, false); - assertTrue(so instanceof ObjectChunk); + assertTrue(so instanceof OffHeapStoredObject); HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]); DataSerializer.writeObjectAsByteArray(so, hdos); DataInputStream in = createInput(hdos); @@ -76,7 +76,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest { public void testByteArrayDataAsAddress() throws IOException, ClassNotFoundException { byte[] expected = new byte[] {1, 2, 3}; StoredObject so = createStoredObject(expected, false, false); - assertTrue(so instanceof DataAsAddress); + assertTrue(so instanceof TinyStoredObject); HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]); DataSerializer.writeObjectAsByteArray(so, hdos); DataInputStream in = createInput(hdos); @@ -88,7 +88,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest { public void testStringChunk() throws IOException, ClassNotFoundException { byte[] expected = EntryEventImpl.serialize("1234567890"); StoredObject so = createStoredObject(expected, true, false); - assertTrue(so instanceof ObjectChunk); + assertTrue(so instanceof OffHeapStoredObject); HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]); DataSerializer.writeObjectAsByteArray(so, hdos); DataInputStream in = createInput(hdos); @@ -101,7 +101,7 @@ public class OffHeapWriteObjectAsByteArrayJUnitTest { public void testStringDataAsAddress() throws IOException, ClassNotFoundException { byte[] expected = EntryEventImpl.serialize("1234"); StoredObject so = createStoredObject(expected, true, false); - assertTrue(so instanceof DataAsAddress); + assertTrue(so instanceof TinyStoredObject); HeapDataOutputStream hdos = new HeapDataOutputStream(new byte[1024]); DataSerializer.writeObjectAsByteArray(so, hdos); DataInputStream in = createInput(hdos); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java index d8c35b8..e9ca59d 100755 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/OldFreeListOffHeapRegionJUnitTest.java @@ -41,7 +41,7 @@ public class OldFreeListOffHeapRegionJUnitTest extends OffHeapRegionBase { @Override public int perObjectOverhead() { - return ObjectChunk.OFF_HEAP_HEADER_SIZE; + return OffHeapStoredObject.HEADER_SIZE; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java index 51f46a1..51bc0a2 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternIntegrationTest.java @@ -84,7 +84,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { private SimpleMemoryAllocatorImpl allocator = null; /** Our test victim's memory slab. */ - private UnsafeMemoryChunk slab = null; + private SlabImpl slab = null; /** * Enables fill validation and creates the test victim. @@ -92,8 +92,8 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { @Before public void setUp() throws Exception { System.setProperty("gemfire.validateOffHeapWithFill", "true"); - this.slab = new UnsafeMemoryChunk(SLAB_SIZE); - this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab}); + this.slab = new SlabImpl(SLAB_SIZE); + this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{this.slab}); } /** @@ -163,7 +163,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { private int totalAllocation = 0; // List of Chunks allocated by this thread - private List<ObjectChunk> chunks = new LinkedList<ObjectChunk>(); + private List<OffHeapStoredObject> chunks = new LinkedList<OffHeapStoredObject>(); // Time to end thread execution private long endTime = System.currentTimeMillis() + RUN_TIME_IN_MILLIS; @@ -173,7 +173,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { */ private void allocate() { int allocation = chunkSizer.allocationSize(); - ObjectChunk chunk = (ObjectChunk) allocator.allocate(allocation); + OffHeapStoredObject chunk = (OffHeapStoredObject) allocator.allocate(allocation); // This should always work just after allocation chunk.validateFill(); @@ -186,7 +186,7 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { * Frees a random chunk from the Chunk list. */ private void free() { - ObjectChunk chunk = chunks.remove(random.nextInt(chunks.size())); + OffHeapStoredObject chunk = chunks.remove(random.nextInt(chunks.size())); totalAllocation -= chunk.getSize(); /* @@ -200,8 +200,8 @@ public class SimpleMemoryAllocatorFillPatternIntegrationTest { * Writes canned data to a random Chunk from the Chunk list. */ private void write() { - ObjectChunk chunk = chunks.get(random.nextInt(chunks.size())); - chunk.writeBytes(0, WRITE_BYTES); + OffHeapStoredObject chunk = chunks.get(random.nextInt(chunks.size())); + chunk.writeDataBytes(0, WRITE_BYTES); } /** http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java index 7c26f86..c61f2f4 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorFillPatternJUnitTest.java @@ -57,7 +57,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { private SimpleMemoryAllocatorImpl allocator = null; /** Our test victim's memory slab. */ - private UnsafeMemoryChunk slab = null; + private SlabImpl slab = null; /** * Enables fill validation and creates the test victim. @@ -65,8 +65,8 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { @Before public void setUp() throws Exception { System.setProperty("gemfire.validateOffHeapWithFill", "true"); - this.slab = new UnsafeMemoryChunk(SLAB_SIZE); - this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{this.slab}); + this.slab = new SlabImpl(SLAB_SIZE); + this.allocator = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{this.slab}); } /** @@ -101,7 +101,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { * Pull a chunk off the fragment. This will have no fill because * it is a "fresh" chunk. */ - ObjectChunk chunk = (ObjectChunk) this.allocator.allocate(chunkSize); + OffHeapStoredObject chunk = (OffHeapStoredObject) this.allocator.allocate(chunkSize); /* * Chunk should have valid fill from initial fragment allocation. @@ -109,7 +109,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { chunk.validateFill(); // "Dirty" the chunk so the release has something to fill over - chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES); + chunk.writeDataBytes(OffHeapStoredObject.MIN_CHUNK_SIZE + 1, WRITE_BYTES); // This should free the Chunk (ref count == 1) chunk.release(); @@ -118,24 +118,24 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { * This chunk should have a fill because it was reused from the * free list (assuming no fragmentation at this point...) */ - chunk = (ObjectChunk) this.allocator.allocate(chunkSize); + chunk = (OffHeapStoredObject) this.allocator.allocate(chunkSize); // Make sure we have a fill this time chunk.validateFill(); // Give the fill code something to write over during the release - chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES); + chunk.writeDataBytes(OffHeapStoredObject.MIN_CHUNK_SIZE + 1, WRITE_BYTES); chunk.release(); // Again, make sure the release implemented the fill chunk.validateFill(); // "Dirty up" the free chunk - chunk.writeBytes(ObjectChunk.MIN_CHUNK_SIZE + 1, WRITE_BYTES); + chunk.writeDataBytes(OffHeapStoredObject.MIN_CHUNK_SIZE + 1, WRITE_BYTES); catchException(chunk).validateFill(); assertTrue(caughtException() instanceof IllegalStateException); - assertEquals("Fill pattern violated for chunk " + chunk.getMemoryAddress() + " with size " + chunk.getSize(), caughtException().getMessage()); + assertEquals("Fill pattern violated for chunk " + chunk.getAddress() + " with size " + chunk.getSize(), caughtException().getMessage()); } @@ -149,14 +149,14 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { /* * Stores our allocated memory. */ - ObjectChunk[] allocatedChunks = new ObjectChunk[COMPACTION_CHUNKS]; + OffHeapStoredObject[] allocatedChunks = new OffHeapStoredObject[COMPACTION_CHUNKS]; /* * Use up most of our memory * Our memory looks like [ ][ ][ ] */ for(int i =0;i < allocatedChunks.length;++i) { - allocatedChunks[i] = (ObjectChunk) this.allocator.allocate(COMPACTION_CHUNK_SIZE); + allocatedChunks[i] = (OffHeapStoredObject) this.allocator.allocate(COMPACTION_CHUNK_SIZE); allocatedChunks[i].validateFill(); } @@ -173,7 +173,7 @@ public class SimpleMemoryAllocatorFillPatternJUnitTest { * our initial chunks. This should force a compaction causing our * memory to look like [ ][ ]. */ - ObjectChunk slightlyLargerChunk = (ObjectChunk) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE); + OffHeapStoredObject slightlyLargerChunk = (OffHeapStoredObject) this.allocator.allocate(FORCE_COMPACTION_CHUNK_SIZE); /* * Make sure the compacted memory has the fill validation. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java index 1f17f9b..cc791fc 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorJUnitTest.java @@ -97,9 +97,9 @@ public class SimpleMemoryAllocatorJUnitTest { LastSevereLogger logger = new LastSevereLogger(); try { SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats, logger, 10, 950, 100, - new AddressableMemoryChunkFactory() { + new SlabFactory() { @Override - public AddressableMemoryChunk create(int size) { + public Slab create(int size) { throw new OutOfMemoryError("expected"); } }); @@ -116,13 +116,13 @@ public class SimpleMemoryAllocatorJUnitTest { LastSevereLogger logger = new LastSevereLogger(); int MAX_SLAB_SIZE = 100; try { - AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() { + SlabFactory factory = new SlabFactory() { private int createCount = 0; @Override - public AddressableMemoryChunk create(int size) { + public Slab create(int size) { createCount++; if (createCount == 1) { - return new UnsafeMemoryChunk(size); + return new SlabImpl(size); } else { throw new OutOfMemoryError("expected"); } @@ -139,10 +139,10 @@ public class SimpleMemoryAllocatorJUnitTest { { NullOutOfOffHeapMemoryListener listener = new NullOutOfOffHeapMemoryListener(); NullOffHeapMemoryStats stats = new NullOffHeapMemoryStats(); - AddressableMemoryChunkFactory factory = new AddressableMemoryChunkFactory() { + SlabFactory factory = new SlabFactory() { @Override - public AddressableMemoryChunk create(int size) { - return new UnsafeMemoryChunk(size); + public Slab create(int size) { + return new SlabImpl(size); } }; MemoryAllocator ma = @@ -156,14 +156,14 @@ public class SimpleMemoryAllocatorJUnitTest { listener = new NullOutOfOffHeapMemoryListener(); NullOffHeapMemoryStats stats2 = new NullOffHeapMemoryStats(); { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); + SlabImpl slab = new SlabImpl(1024); try { - SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl.createForUnitTest(listener, stats2, new SlabImpl[]{slab}); } catch (IllegalStateException expected) { assertTrue("unexpected message: " + expected.getMessage(), expected.getMessage().equals("attempted to reuse existing off-heap memory even though new off-heap memory was allocated")); } finally { - slab.release(); + slab.free(); } assertFalse(stats.isClosed()); assertTrue(listener.isClosed()); @@ -189,23 +189,23 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testBasics() { int BATCH_SIZE = 1; - int TINY_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.TINY_MULTIPLE; - int HUGE_MULTIPLE = com.gemstone.gemfire.internal.offheap.FreeListManager.HUGE_MULTIPLE; - int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE; - int maxTiny = com.gemstone.gemfire.internal.offheap.FreeListManager.MAX_TINY-perObjectOverhead; + int TINY_MULTIPLE = FreeListManager.TINY_MULTIPLE; + int HUGE_MULTIPLE = FreeListManager.HUGE_MULTIPLE; + int perObjectOverhead = OffHeapStoredObject.HEADER_SIZE; + int maxTiny = FreeListManager.MAX_TINY-perObjectOverhead; int minHuge = maxTiny+1; int TOTAL_MEM = (maxTiny+perObjectOverhead)*BATCH_SIZE /*+ (maxBig+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+1+perObjectOverhead)*BATCH_SIZE + (TINY_MULTIPLE+perObjectOverhead)*BATCH_SIZE /*+ (MIN_BIG_SIZE+perObjectOverhead)*BATCH_SIZE*/ + round(TINY_MULTIPLE, minHuge+perObjectOverhead+1); - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM); + SlabImpl slab = new SlabImpl(TOTAL_MEM); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); assertEquals(TOTAL_MEM, ma.getFreeMemory()); assertEquals(TOTAL_MEM, ma.freeList.getFreeFragmentMemory()); assertEquals(0, ma.freeList.getFreeTinyMemory()); assertEquals(0, ma.freeList.getFreeHugeMemory()); - MemoryChunk tinymc = ma.allocate(maxTiny); + StoredObject tinymc = ma.allocate(maxTiny); assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory()); assertEquals(round(TINY_MULTIPLE, maxTiny+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeTinyMemory()); - MemoryChunk hugemc = ma.allocate(minHuge); + StoredObject hugemc = ma.allocate(minHuge); assertEquals(TOTAL_MEM-round(TINY_MULTIPLE, minHuge+perObjectOverhead)/*-round(BIG_MULTIPLE, maxBig+perObjectOverhead)*/-round(TINY_MULTIPLE, maxTiny+perObjectOverhead), ma.getFreeMemory()); long freeSlab = ma.freeList.getFreeFragmentMemory(); long oldFreeHugeMemory = ma.freeList.getFreeHugeMemory(); @@ -249,7 +249,7 @@ public class SimpleMemoryAllocatorJUnitTest { hugemc = ma.allocate(minHuge); assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory()); if (BATCH_SIZE > 1) { - MemoryChunk hugemc2 = ma.allocate(minHuge); + StoredObject hugemc2 = ma.allocate(minHuge); assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-2), ma.freeList.getFreeHugeMemory()); hugemc2.release(); assertEquals(round(TINY_MULTIPLE, minHuge+perObjectOverhead)*(BATCH_SIZE-1), ma.freeList.getFreeHugeMemory()); @@ -265,15 +265,15 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testChunkCreateDirectByteBuffer() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024); + SlabImpl slab = new SlabImpl(1024*1024); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); ByteBuffer bb = ByteBuffer.allocate(1024); for (int i=0; i < 1024; i++) { bb.put((byte) i); } bb.position(0); - ObjectChunk c = (ObjectChunk) ma.allocateAndInitialize(bb.array(), false, false); + OffHeapStoredObject c = (OffHeapStoredObject) ma.allocateAndInitialize(bb.array(), false, false); assertEquals(1024, c.getDataSize()); if (!Arrays.equals(bb.array(), c.getRawBytes())) { fail("arrays are not equal. Expected " + Arrays.toString(bb.array()) + " but found: " + Arrays.toString(c.getRawBytes())); @@ -293,9 +293,9 @@ public class SimpleMemoryAllocatorJUnitTest { } @Test public void testGetLostChunks() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024); + SlabImpl slab = new SlabImpl(1024*1024); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); assertEquals(Collections.emptyList(), ma.getLostChunks()); } finally { SimpleMemoryAllocatorImpl.freeOffHeapMemory(); @@ -304,9 +304,9 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testFindSlab() { final int SLAB_SIZE = 1024*1024; - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE); + SlabImpl slab = new SlabImpl(SLAB_SIZE); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); assertEquals(0, ma.findSlab(slab.getMemoryAddress())); assertEquals(0, ma.findSlab(slab.getMemoryAddress()+SLAB_SIZE-1)); try { @@ -326,9 +326,9 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testValidateAddressAndSize() { final int SLAB_SIZE = 1024*1024; - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE); + SlabImpl slab = new SlabImpl(SLAB_SIZE); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); try { SimpleMemoryAllocatorImpl.validateAddress(0L); fail("expected IllegalStateException"); @@ -363,9 +363,9 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testMemoryInspection() { final int SLAB_SIZE = 1024*1024; - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(SLAB_SIZE); + SlabImpl slab = new SlabImpl(SLAB_SIZE); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); MemoryInspector inspector = ma.getMemoryInspector(); assertNotNull(inspector); assertEquals(null, inspector.getFirstBlock()); @@ -382,7 +382,7 @@ public class SimpleMemoryAllocatorJUnitTest { assertEquals(1024*1024, firstBlock.getBlockSize()); assertEquals("N/A", firstBlock.getDataType()); assertEquals(-1, firstBlock.getFreeListId()); - assertTrue(firstBlock.getMemoryAddress() > 0); + assertTrue(firstBlock.getAddress() > 0); assertNull(firstBlock.getNextBlock()); assertEquals(0, firstBlock.getRefCount()); assertEquals(0, firstBlock.getSlabId()); @@ -401,9 +401,9 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testClose() { System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "false"); - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024*1024); + SlabImpl slab = new SlabImpl(1024*1024); boolean freeSlab = true; - UnsafeMemoryChunk[] slabs = new UnsafeMemoryChunk[]{slab}; + SlabImpl[] slabs = new SlabImpl[]{slab}; try { SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), slabs); ma.close(); @@ -427,23 +427,23 @@ public class SimpleMemoryAllocatorJUnitTest { @Test public void testCompaction() { - final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE; + final int perObjectOverhead = OffHeapStoredObject.HEADER_SIZE; final int BIG_ALLOC_SIZE = 150000; final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2; final int TOTAL_MEM = BIG_ALLOC_SIZE; - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM); + SlabImpl slab = new SlabImpl(TOTAL_MEM); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); + StoredObject bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead); try { - MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); + StoredObject smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); fail("Expected out of memory"); } catch (OutOfOffHeapMemoryException expected) { } bmc.release(); assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory()); - MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); - MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); + StoredObject smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); + StoredObject smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); smc2.release(); assertEquals(TOTAL_MEM-SMALL_ALLOC_SIZE, ma.freeList.getFreeMemory()); try { @@ -456,7 +456,7 @@ public class SimpleMemoryAllocatorJUnitTest { bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead); bmc.release(); assertEquals(TOTAL_MEM, ma.freeList.getFreeMemory()); - ArrayList<MemoryChunk> mcs = new ArrayList<MemoryChunk>(); + ArrayList<StoredObject> mcs = new ArrayList<StoredObject>(); for (int i=0; i < BIG_ALLOC_SIZE/(8+perObjectOverhead); i++) { mcs.add(ma.allocate(8)); } @@ -492,11 +492,11 @@ public class SimpleMemoryAllocatorJUnitTest { assertEquals((8+perObjectOverhead)*6, ma.freeList.getFreeMemory()); checkMcs(mcs); // At this point I should have 8*6 + perObjectOverhead*6 of free memory - MemoryChunk mc24 = ma.allocate(24); + StoredObject mc24 = ma.allocate(24); checkMcs(mcs); assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead), ma.freeList.getFreeMemory()); // At this point I should have 8*3 + perObjectOverhead*5 of free memory - MemoryChunk mc16 = ma.allocate(16); + StoredObject mc16 = ma.allocate(16); checkMcs(mcs); assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead), ma.freeList.getFreeMemory()); // At this point I should have 8*1 + perObjectOverhead*4 of free memory @@ -504,7 +504,7 @@ public class SimpleMemoryAllocatorJUnitTest { checkMcs(mcs); assertEquals((8+perObjectOverhead)*6 - (24+perObjectOverhead) - (16+perObjectOverhead) - (8+perObjectOverhead), ma.freeList.getFreeMemory()); // At this point I should have 8*0 + perObjectOverhead*3 of free memory - MemoryChunk mcDO = ma.allocate(perObjectOverhead*2); + StoredObject mcDO = ma.allocate(perObjectOverhead*2); checkMcs(mcs); // At this point I should have 8*0 + perObjectOverhead*0 of free memory assertEquals(0, ma.freeList.getFreeMemory()); @@ -525,7 +525,7 @@ public class SimpleMemoryAllocatorJUnitTest { assertEquals((perObjectOverhead*3)+(8+perObjectOverhead)+(16+perObjectOverhead)+(24+perObjectOverhead), ma.freeList.getFreeMemory()); long freeMem = ma.freeList.getFreeMemory(); - for (MemoryChunk mc: mcs) { + for (StoredObject mc: mcs) { mc.release(); assertEquals(freeMem+(8+perObjectOverhead), ma.freeList.getFreeMemory()); freeMem += (8+perObjectOverhead); @@ -543,11 +543,11 @@ public class SimpleMemoryAllocatorJUnitTest { boolean memoryUsageEventReceived; @Test public void testUsageEventListener() { - final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE; + final int perObjectOverhead = OffHeapStoredObject.HEADER_SIZE; final int SMALL_ALLOC_SIZE = 1000; - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(3000); + SlabImpl slab = new SlabImpl(3000); try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); MemoryUsageListener listener = new MemoryUsageListener() { @Override public void updateMemoryUsed(final long bytesUsed) { @@ -559,7 +559,7 @@ public class SimpleMemoryAllocatorJUnitTest { this.expectedMemoryUsage = SMALL_ALLOC_SIZE; this.memoryUsageEventReceived = false; - MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); + StoredObject smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); assertEquals(true, this.memoryUsageEventReceived); this.expectedMemoryUsage = SMALL_ALLOC_SIZE * 2; @@ -588,19 +588,19 @@ public class SimpleMemoryAllocatorJUnitTest { SimpleMemoryAllocatorImpl.freeOffHeapMemory(); } } - private void checkMcs(ArrayList<MemoryChunk> mcs) { - for (MemoryChunk mc: mcs) { + private void checkMcs(ArrayList<StoredObject> mcs) { + for (StoredObject mc: mcs) { assertEquals(8+8, mc.getSize()); } } @Test public void testOutOfOffHeapMemory() { - final int perObjectOverhead = com.gemstone.gemfire.internal.offheap.ObjectChunk.OFF_HEAP_HEADER_SIZE; + final int perObjectOverhead = OffHeapStoredObject.HEADER_SIZE; final int BIG_ALLOC_SIZE = 150000; final int SMALL_ALLOC_SIZE = BIG_ALLOC_SIZE/2; final int TOTAL_MEM = BIG_ALLOC_SIZE; - final UnsafeMemoryChunk slab = new UnsafeMemoryChunk(TOTAL_MEM); + final SlabImpl slab = new SlabImpl(TOTAL_MEM); final AtomicReference<OutOfOffHeapMemoryException> ooom = new AtomicReference<OutOfOffHeapMemoryException>(); final OutOfOffHeapMemoryListener oooml = new OutOfOffHeapMemoryListener() { @Override @@ -612,13 +612,13 @@ public class SimpleMemoryAllocatorJUnitTest { } }; try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(oooml, new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(oooml, new NullOffHeapMemoryStats(), new SlabImpl[]{slab}); // make a big allocation - MemoryChunk bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead); + StoredObject bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead); assertNull(ooom.get()); // drive the ma to ooom with small allocations try { - MemoryChunk smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); + StoredObject smc = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead); fail("Expected out of memory"); } catch (OutOfOffHeapMemoryException expected) { } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java index feb5de8..48a0e25 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/StoredObjectTestSuite.java @@ -21,10 +21,10 @@ import org.junit.runner.RunWith; import org.junit.runners.Suite; @Suite.SuiteClasses({ - DataAsAddressJUnitTest.class, - ObjectChunkJUnitTest.class, - ObjectChunkWithHeapFormJUnitTest.class, - ObjectChunkSliceJUnitTest.class, + TinyStoredObjectJUnitTest.class, + OffHeapStoredObjectJUnitTest.class, + OffHeapStoredObjectWithHeapFormJUnitTest.class, + OffHeapStoredObjectSliceJUnitTest.class, }) @RunWith(Suite.class) public class StoredObjectTestSuite { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3087c86f/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java deleted file mode 100644 index 3ae6159..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/internal/offheap/SyncChunkStackJUnitTest.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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 com.gemstone.gemfire.internal.offheap; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.MethodInvocationReport; - -import com.gemstone.gemfire.LogWriter; -import com.gemstone.gemfire.test.junit.categories.UnitTest; - -@Category(UnitTest.class) -public class SyncChunkStackJUnitTest { - static { - ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); - } - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void addressZeroCausesStackToBeEmpty() { - SyncChunkStack stack = new SyncChunkStack(0L); - assertEquals(true, stack.isEmpty()); - } - - @Test - public void defaultStackIsEmpty() { - SyncChunkStack stack = new SyncChunkStack(); - assertEquals(true, stack.isEmpty()); - } - - @Test - public void defaultStackReturnsZeroFromTop() { - SyncChunkStack stack = new SyncChunkStack(); - assertEquals(0L, stack.getTopAddress()); - } - - @Test - public void defaultStackReturnsZeroFromPoll() { - SyncChunkStack stack = new SyncChunkStack(); - assertEquals(0L, stack.poll()); - } - - @Test - public void defaultStackReturnsZeroFromClear() { - SyncChunkStack stack = new SyncChunkStack(); - assertEquals(0L, stack.clear()); - assertEquals(true, stack.isEmpty()); - } - - @Test - public void defaultStackLogsNothing() { - SyncChunkStack stack = new SyncChunkStack(); - LogWriter lw = mock(LogWriter.class, withSettings().invocationListeners(new InvocationListener() { - @Override - public void reportInvocation(MethodInvocationReport methodInvocationReport) { - fail("Unexpected invocation"); - } - })); - stack.logSizes(lw, "should not be used"); - } - - @Test - public void defaultStackComputeSizeIsZero() { - SyncChunkStack stack = new SyncChunkStack(); - assertEquals(0L, stack.computeTotalSize()); - } - - @Test - public void stackCreatedWithAddressIsNotEmpty() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - - SyncChunkStack stack = new SyncChunkStack(chunk.getMemoryAddress()); - assertEquals(false, stack.isEmpty()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - @Test - public void stackWithChunkIsNotEmpty() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(chunk.getMemoryAddress()); - assertEquals(false, stack.isEmpty()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - @Test - public void stackWithChunkTopEqualsAddress() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - - long addr = chunk.getMemoryAddress(); - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(addr); - assertEquals(addr, stack.getTopAddress()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - @Test - public void addressZeroOfferCausesFailedAssertion() { - SyncChunkStack stack = new SyncChunkStack(0L); - try { - stack.offer(0); - fail("expected AssertionError"); - } catch (AssertionError expected) { - } - } - - - @Test - public void stackWithChunkClearReturnsAddressAndEmptiesStack() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - - long addr = chunk.getMemoryAddress(); - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(addr); - long clearAddr = stack.clear(); - assertEquals(addr, clearAddr); - assertEquals(true, stack.isEmpty()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - @Test - public void stackWithChunkPollReturnsAddressAndEmptiesStack() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - - long addr = chunk.getMemoryAddress(); - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(addr); - long pollAddr = stack.poll(); - assertEquals(addr, pollAddr); - assertEquals(true, stack.isEmpty()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - @Test - public void stackWithChunkTotalSizeIsChunkSize() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - int chunkSize = chunk.getSize(); - - long addr = chunk.getMemoryAddress(); - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(addr); - assertEquals(chunkSize, stack.computeTotalSize()); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - - @Test - public void stackWithChunkLogShowsMsgAndSize() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - int chunkSize = chunk.getSize(); - - long addr = chunk.getMemoryAddress(); - SyncChunkStack stack = new SyncChunkStack(); - stack.offer(addr); - LogWriter lw = mock(LogWriter.class); - stack.logSizes(lw, "foo"); - verify(lw).info("foo"+chunkSize); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - private class TestableSyncChunkStack extends SyncChunkStack { - public boolean doConcurrentMod = true; - public int chunk2Size; - private SimpleMemoryAllocatorImpl ma; - TestableSyncChunkStack(SimpleMemoryAllocatorImpl ma) { - this.ma = ma; - } - @Override - protected void testHookDoConcurrentModification() { - if (doConcurrentMod) { - doConcurrentMod = false; - ObjectChunk chunk2 = (ObjectChunk) ma.allocate(50); - this.chunk2Size = chunk2.getSize(); - this.offer(chunk2.getMemoryAddress()); - } - } - } - @Test - public void stackWithChunkTotalSizeIsChunkSizeWithConcurrentMod() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - int chunkSize = chunk.getSize(); - - long addr = chunk.getMemoryAddress(); - TestableSyncChunkStack stack = new TestableSyncChunkStack(ma); - stack.offer(addr); - long totalSize = stack.computeTotalSize(); - assertEquals("chunkSize=" + chunkSize + " chunk2Size=" + stack.chunk2Size, chunkSize + stack.chunk2Size, totalSize); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } - - - @Test - public void stackWithChunkLogShowsMsgAndSizeWithConcurrentMod() { - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); - try { - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - ObjectChunk chunk = (ObjectChunk) ma.allocate(100); - int chunkSize = chunk.getSize(); - - long addr = chunk.getMemoryAddress(); - TestableSyncChunkStack stack = new TestableSyncChunkStack(ma); - stack.offer(addr); - LogWriter lw = mock(LogWriter.class); - stack.logSizes(lw, "foo"); - verify(lw).info("foo"+chunkSize); - verify(lw).info("foo"+stack.chunk2Size); - } finally { - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - } -}
