org.terracotta.modules.ehcache.writebehind.AsyncWriteBehind Maven / Gradle / Ivy
/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*/
package org.terracotta.modules.ehcache.writebehind;
import net.sf.ehcache.CacheEntry;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.writer.CacheWriter;
import net.sf.ehcache.writer.writebehind.OperationsFilter;
import net.sf.ehcache.writer.writebehind.WriteBehind;
import org.terracotta.modules.ehcache.async.AsyncCoordinator;
import org.terracotta.modules.ehcache.async.scatterpolicies.ItemScatterPolicy;
import org.terracotta.modules.ehcache.writebehind.operations.DeleteAsyncOperation;
import org.terracotta.modules.ehcache.writebehind.operations.SingleAsyncOperation;
import org.terracotta.modules.ehcache.writebehind.operations.WriteAsyncOperation;
public class AsyncWriteBehind implements WriteBehind {
public static final ItemScatterPolicy POLICY = new SingleAsyncOperationItemScatterPolicy();
private final AsyncCoordinator async;
private final int concurrency;
/**
* Instantiate a new instance of {@code AsyncWriteBehind} by providing the async coordinator instance that will be
* used for the underlying behavior.
*
* @param async the async coordinator instance that will be used by the write behind queue
* @param writeBehindConcurrency the amount of buckets and threads to use
*/
public AsyncWriteBehind(final AsyncCoordinator async, final int writeBehindConcurrency) {
if(async == null) {
throw new IllegalArgumentException("AsyncCoordinator can't be null");
}
if(writeBehindConcurrency < 1) {
throw new IllegalArgumentException("writeBehindConcurrency has to be at least one");
}
this.async = async;
this.concurrency = writeBehindConcurrency;
}
@Override
public void start(CacheWriter writer) throws CacheException {
async.start(new CacheWriterProcessor(writer), concurrency, POLICY);
}
// This method is to be called from within a clustered Lock as it does not take any clustered lock inside.
@Override
public void write(Element element) {
async.add(new WriteAsyncOperation(element));
}
// This method is to be called from within a clustered Lock as it does not take any clustered lock inside.
@Override
public void delete(CacheEntry entry) {
async.add(new DeleteAsyncOperation(entry.getKey(), entry.getElement()));
}
@Override
public void setOperationsFilter(OperationsFilter filter) {
OperationsFilterWrapper filterWrapper = new OperationsFilterWrapper(filter);
async.setOperationsFilter(filterWrapper);
}
@Override
public void stop() throws CacheException {
async.stop();
}
@Override
public long getQueueSize() {
return async.getQueueSize();
}
private static class SingleAsyncOperationItemScatterPolicy implements ItemScatterPolicy {
private SingleAsyncOperationItemScatterPolicy() {
//
}
@Override
public int selectBucket(final int count, final SingleAsyncOperation item) {
Object key;
try {
key = item.getKey();
} catch (Exception e) {
throw new CacheException(e);
}
return Math.abs(key.hashCode() % count);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy