/*
* Copyright 2015 Terracotta, Inc., a Software AG company.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terracotta.offheapstore.disk.persistent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.junit.Assert;
import org.junit.Test;
import org.terracotta.offheapstore.disk.AbstractDiskTest;
import org.terracotta.offheapstore.disk.paging.MappedPageSource;
import org.terracotta.offheapstore.disk.storage.FileBackedStorageEngine;
import org.terracotta.offheapstore.disk.storage.PersistentIntegerStorageEngine;
import org.terracotta.offheapstore.disk.storage.PersistentSplitStorageEngine;
import org.terracotta.offheapstore.disk.storage.portability.PersistentByteArrayPortability;
import org.terracotta.offheapstore.disk.storage.portability.PersistentSerializablePortability;
import org.terracotta.offheapstore.util.MemoryUnit;
/**
*
* @author Chris Dennis
*/
public class PersistentConcurrentOffHeapMapIT extends AbstractDiskTest {
@Test
public void testTableOnlyPersistence() throws IOException {
byte[] indexData;
PersistentConcurrentOffHeapHashMap<Integer, Integer> map = new PersistentConcurrentOffHeapHashMap<Integer, Integer>(new MappedPageSource(dataFile), PersistentSplitStorageEngine.createPersistentFactory(PersistentIntegerStorageEngine.createPersistentFactory(), PersistentIntegerStorageEngine.createPersistentFactory()));
try {
for (int i = 0; i < 100; i++) {
map.put(Integer.valueOf(i), Integer.valueOf(i));
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
try {
map.flush();
map.persist(oout);
} finally {
oout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Integer, Integer> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream oin = new ObjectInputStream(bin);
try {
clone = new PersistentConcurrentOffHeapHashMap<Integer, Integer>(oin, new MappedPageSource(dataFile, false), PersistentSplitStorageEngine.createPersistentFactory(PersistentIntegerStorageEngine.createPersistentFactory(), PersistentIntegerStorageEngine.createPersistentFactory()));
clone.bootstrap(oin);
} finally {
oin.close();
}
Assert.assertEquals(100, clone.size());
for (int i = 0; i < 100; i++) {
Assert.assertEquals(i, clone.get(i).intValue());
}
} finally {
if (clone != null) {
clone.close();
}
}
}
@Test
public void testFullPersistence() throws IOException {
byte[] indexData;
long occupiedSize = -1;
MappedPageSource source = new MappedPageSource(dataFile);
PersistentConcurrentOffHeapHashMap<Integer, byte[]> map = new PersistentConcurrentOffHeapHashMap<Integer, byte[]>(source, FileBackedStorageEngine.createFactory(source, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), PersistentByteArrayPortability.INSTANCE));
try {
for (int i = 0; i < 100; i++) {
map.put(Integer.valueOf(i), new byte[i]);
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream dout = new ObjectOutputStream(bout);
occupiedSize = map.getOccupiedMemory();
try {
map.flush();
map.persist(dout);
} finally {
dout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Integer, byte[]> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream din = new ObjectInputStream(bin);
try {
MappedPageSource clonedSource = new MappedPageSource(dataFile, false);
clone = new PersistentConcurrentOffHeapHashMap<Integer, byte[]>(din, clonedSource, FileBackedStorageEngine.createFactory(clonedSource, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), PersistentByteArrayPortability.INSTANCE, false));
clone.bootstrap(din);
} finally {
din.close();
}
Assert.assertEquals(100, clone.size());
Assert.assertEquals(occupiedSize, clone.getOccupiedMemory());
for (int i = 0; i < 100; i++) {
Assert.assertEquals(i, clone.get(i).length);
}
} finally {
if (clone != null) {
clone.close();
}
}
}
@Test
public void testSerializableValuesPersistence() throws IOException {
byte[] indexData;
MappedPageSource source = new MappedPageSource(dataFile);
PersistentConcurrentOffHeapHashMap<Integer, Serializable> map = new PersistentConcurrentOffHeapHashMap<Integer, Serializable>(source, FileBackedStorageEngine.createFactory(source, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability()));
try {
for (int i = 0; i < 100; i++) {
map.put(Integer.valueOf(i), "Hello World");
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream dout = new ObjectOutputStream(bout);
try {
map.flush();
map.persist(dout);
} finally {
dout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Integer, Serializable> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream din = new ObjectInputStream(bin);
try {
MappedPageSource clonedSource = new MappedPageSource(dataFile, false);
clone = new PersistentConcurrentOffHeapHashMap<Integer, Serializable>(din, clonedSource, FileBackedStorageEngine.createFactory(clonedSource, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability(), false));
clone.bootstrap(din);
} finally {
din.close();
}
Assert.assertEquals(100, clone.size());
for (int i = 0; i < 100; i++) {
Assert.assertEquals("Hello World", clone.get(i));
}
} finally {
if (clone != null) {
clone.close();
}
}
}
@Test
public void testSerializableValuesPersistenceWithNewTypes() throws IOException {
byte[] indexData;
MappedPageSource source = new MappedPageSource(dataFile);
PersistentConcurrentOffHeapHashMap<Number, Serializable> map = new PersistentConcurrentOffHeapHashMap<Number, Serializable>(source, FileBackedStorageEngine.createFactory(source, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability()));
try {
for (int i = 0; i < 100; i++) {
map.put(Integer.valueOf(i), "Hello World");
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream dout = new ObjectOutputStream(bout);
try {
map.flush();
map.persist(dout);
} finally {
dout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Number, Serializable> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream din = new ObjectInputStream(bin);
try {
MappedPageSource clonedSource = new MappedPageSource(dataFile, false);
clone = new PersistentConcurrentOffHeapHashMap<Number, Serializable>(din, clonedSource, FileBackedStorageEngine.createFactory(clonedSource, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability(), false));
clone.bootstrap(din);
} finally {
din.close();
}
Assert.assertEquals(100, clone.size());
for (int i = 0; i < 100; i++) {
Assert.assertEquals("Hello World", clone.get(i));
}
for (long i = 0L; i < 100L; i++) {
clone.put(Long.valueOf(i), "Hello World");
}
Assert.assertEquals(200, clone.size());
for (int i = 0; i < 100; i++) {
Assert.assertEquals("Hello World", clone.get(i));
}
for (long i = 0L; i < 100L; i++) {
Assert.assertEquals("Hello World", clone.get(i));
}
} finally {
if (clone != null) {
clone.close();
}
}
}
@Test
public void testPersistenceOfPrimitiveClassType() throws IOException {
final Class<?>[] primitives = new Class<?>[]{double.class, long.class, float.class, int.class, char.class,
short.class, byte.class, boolean.class, void.class};
byte[] indexData;
MappedPageSource source = new MappedPageSource(dataFile);
PersistentConcurrentOffHeapHashMap<Integer, Serializable> map = new PersistentConcurrentOffHeapHashMap<Integer, Serializable>(source, FileBackedStorageEngine.createFactory(source, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability()));
try {
for (int i = 0; i < primitives.length; i++) {
map.put(Integer.valueOf(i), primitives[i]);
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream dout = new ObjectOutputStream(bout);
try {
map.flush();
map.persist(dout);
} finally {
dout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Integer, Serializable> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream din = new ObjectInputStream(bin);
try {
MappedPageSource clonedSource = new MappedPageSource(dataFile, false);
clone = new PersistentConcurrentOffHeapHashMap<Integer, Serializable>(din, clonedSource, FileBackedStorageEngine.createFactory(clonedSource, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), new PersistentSerializablePortability(), false));
clone.bootstrap(din);
} finally {
din.close();
}
Assert.assertEquals(primitives.length, clone.size());
for (int i = 0; i < primitives.length; i++) {
Assert.assertSame(primitives[i], clone.get(i));
}
} finally {
if (clone != null) {
clone.close();
}
}
}
@Test
public void testFragmentedPersistence() throws IOException {
byte[] indexData;
MappedPageSource source = new MappedPageSource(dataFile);
PersistentConcurrentOffHeapHashMap<Integer, byte[]> map = new PersistentConcurrentOffHeapHashMap<Integer, byte[]>(source, FileBackedStorageEngine.createFactory(source, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), PersistentByteArrayPortability.INSTANCE));
try {
for (int i = 0; i < 100; i++) {
map.put(Integer.valueOf(i), new byte[i]);
}
for (int i = 0; i < 100; i+=2) {
map.remove(Integer.valueOf(i));
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream dout = new ObjectOutputStream(bout);
try {
map.flush();
map.persist(dout);
} finally {
dout.close();
}
indexData = bout.toByteArray();
} finally {
map.close();
}
PersistentConcurrentOffHeapHashMap<Integer, byte[]> clone = null;
try {
ByteArrayInputStream bin = new ByteArrayInputStream(indexData);
ObjectInputStream din = new ObjectInputStream(bin);
try {
MappedPageSource clonedSource = new MappedPageSource(dataFile, false);
clone = new PersistentConcurrentOffHeapHashMap<Integer, byte[]>(din, clonedSource, FileBackedStorageEngine.createFactory(clonedSource, Long.MAX_VALUE, MemoryUnit.BYTES, new PersistentSerializablePortability(), PersistentByteArrayPortability.INSTANCE, false));
clone.bootstrap(din);
} finally {
din.close();
}
Assert.assertEquals(50, clone.size());
for (int i = 1; i < 100; i+=2) {
Assert.assertEquals(i, clone.get(i).length);
}
} finally {
if (clone != null) {
clone.close();
}
}
}
}