/* * 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; import org.terracotta.offheapstore.WriteLockedOffHeapClockCache; import java.util.Map; import java.util.Random; import org.junit.Assert; import org.junit.Test; import org.terracotta.offheapstore.buffersource.HeapBufferSource; import org.terracotta.offheapstore.paging.PageSource; import org.terracotta.offheapstore.paging.UnlimitedPageSource; import org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource; import org.terracotta.offheapstore.storage.IntegerStorageEngine; import org.terracotta.offheapstore.storage.OffHeapBufferHalfStorageEngine; import org.terracotta.offheapstore.storage.SplitStorageEngine; import org.terracotta.offheapstore.storage.StorageEngine; import org.terracotta.offheapstore.storage.portability.ByteArrayPortability; import org.terracotta.offheapstore.util.MemoryUnit; public class ExtremeTableMutatingIT { @Test public void testExtremeTableMutations() { PageSource source = new UpfrontAllocatingPageSource(new HeapBufferSource(), MemoryUnit.MEGABYTES.toBytes(1), MemoryUnit.MEGABYTES.toBytes(1)); StorageEngine<Integer, byte[]> storage = new SplitStorageEngine<Integer, byte[]>(new IntegerStorageEngine(), new OffHeapBufferHalfStorageEngine<byte[]>(source, MemoryUnit.KILOBYTES.toBytes(4), ByteArrayPortability.INSTANCE)); Map<Integer, byte[]> cache = new EvilOffHeapClockCache<Integer, byte[]>(new UnlimitedPageSource(new HeapBufferSource()), storage); int i; for (i = 0; i == cache.size(); i++) { cache.put(i, new byte[i % 1024]); } for (int c = 0; c < i * 10; c++) { cache.put(i + c, new byte[(i + c) % 1024]); } for (int n = 0; n < i * 11; n++) { byte[] array = cache.get(n); if (array != null) { Assert.assertEquals(n % 1024, array.length); } } } static class EvilOffHeapClockCache<K, V> extends WriteLockedOffHeapClockCache<K, V> { private final Random rndm = new Random(); public EvilOffHeapClockCache(PageSource source, StorageEngine<? super K, ? super V> storageEngine) { super(source, storageEngine); } @Override protected void storageEngineFailure(Object failure) { if (rndm.nextFloat() < 0.1f) { clear(); } else { super.storageEngineFailure(failure); } } } }