/*
* Copyright Terracotta, Inc.
*
* 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.ehcache.impl.internal.store.disk;
import org.ehcache.config.Eviction;
import org.ehcache.config.EvictionAdvisor;
import org.ehcache.impl.internal.store.disk.factories.EhcachePersistentSegmentFactory;
import org.ehcache.impl.internal.store.offheap.AbstractEhcacheOffHeapBackingMapTest;
import org.ehcache.impl.internal.store.offheap.EhcacheOffHeapBackingMap;
import org.ehcache.impl.internal.store.offheap.SwitchableEvictionAdvisor;
import org.ehcache.impl.internal.store.offheap.HeuristicConfiguration;
import org.ehcache.impl.internal.store.offheap.factories.EhcacheSegmentFactory.EhcacheSegment.EvictionListener;
import org.ehcache.impl.internal.store.offheap.portability.SerializerPortability;
import org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider;
import org.ehcache.spi.serialization.SerializationProvider;
import org.ehcache.spi.serialization.Serializer;
import org.ehcache.spi.serialization.UnsupportedTypeException;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.terracotta.offheapstore.disk.paging.MappedPageSource;
import org.terracotta.offheapstore.disk.persistent.PersistentPortability;
import org.terracotta.offheapstore.disk.storage.FileBackedStorageEngine;
import org.terracotta.offheapstore.util.Factory;
import java.io.IOException;
import static org.ehcache.config.Eviction.noAdvice;
import static org.ehcache.impl.internal.store.disk.OffHeapDiskStore.persistent;
import static org.ehcache.impl.internal.spi.TestServiceProvider.providerContaining;
import static org.mockito.Mockito.mock;
import static org.terracotta.offheapstore.util.MemoryUnit.BYTES;
public class EhcachePersistentConcurrentOffHeapClockCacheTest extends AbstractEhcacheOffHeapBackingMapTest {
@Rule
public final TemporaryFolder folder = new TemporaryFolder();
@Override
@SuppressWarnings("unchecked")
protected EhcachePersistentConcurrentOffHeapClockCache<String, String> createTestSegment() throws IOException {
return createTestSegment(noAdvice(), mock(EvictionListener.class));
}
@Override
@SuppressWarnings("unchecked")
protected EhcacheOffHeapBackingMap<String, String> createTestSegment(EvictionAdvisor<? super String, ? super String> evictionPredicate) throws IOException {
return createTestSegment(evictionPredicate, mock(EvictionListener.class));
}
private EhcachePersistentConcurrentOffHeapClockCache<String, String> createTestSegment(final EvictionAdvisor<? super String, ? super String> evictionPredicate, EvictionListener<String, String> evictionListener) throws IOException {
try {
HeuristicConfiguration configuration = new HeuristicConfiguration(1024 * 1024);
SerializationProvider serializationProvider = new DefaultSerializationProvider(null);
serializationProvider.start(providerContaining());
MappedPageSource pageSource = new MappedPageSource(folder.newFile(), true, configuration.getMaximumSize());
Serializer<String> keySerializer = serializationProvider.createKeySerializer(String.class, EhcachePersistentConcurrentOffHeapClockCacheTest.class.getClassLoader());
Serializer<String> valueSerializer = serializationProvider.createValueSerializer(String.class, EhcachePersistentConcurrentOffHeapClockCacheTest.class.getClassLoader());
PersistentPortability<String> keyPortability = persistent(new SerializerPortability<String>(keySerializer));
PersistentPortability<String> elementPortability = persistent(new SerializerPortability<String>(valueSerializer));
Factory<FileBackedStorageEngine<String, String>> storageEngineFactory = FileBackedStorageEngine.createFactory(pageSource, configuration.getMaximumSize() / 10, BYTES, keyPortability, elementPortability);
SwitchableEvictionAdvisor<String, String> wrappedEvictionAdvisor = new SwitchableEvictionAdvisor<String, String>() {
private volatile boolean enabled = true;
@Override
public boolean adviseAgainstEviction(String key, String value) {
return evictionPredicate.adviseAgainstEviction(key, value);
}
@Override
public boolean isSwitchedOn() {
return enabled;
}
@Override
public void setSwitchedOn(boolean switchedOn) {
this.enabled = switchedOn;
}
};
EhcachePersistentSegmentFactory<String, String> segmentFactory = new EhcachePersistentSegmentFactory<String, String>(pageSource, storageEngineFactory, 0, wrappedEvictionAdvisor, evictionListener, true);
return new EhcachePersistentConcurrentOffHeapClockCache<String, String>(evictionPredicate, segmentFactory, 1);
} catch (UnsupportedTypeException e) {
throw new AssertionError(e);
}
}
@Override
protected void destroySegment(EhcacheOffHeapBackingMap<String, String> segment) {
((EhcachePersistentConcurrentOffHeapClockCache<String, String>)segment).destroy();
}
@Override
protected void putPinned(String key, String value, EhcacheOffHeapBackingMap<String, String> segment) {
((EhcachePersistentConcurrentOffHeapClockCache<String, String>) segment).putPinned(key, value);
}
@Override
protected boolean isPinned(String key, EhcacheOffHeapBackingMap<String, String> segment) {
return ((EhcachePersistentConcurrentOffHeapClockCache<String, String>) segment).isPinned(key);
}
@Override
protected int getMetadata(String key, int mask, EhcacheOffHeapBackingMap<String, String> segment) {
return ((EhcachePersistentConcurrentOffHeapClockCache<String, String>) segment).getMetadata(key, mask);
}
}