package com.thinkaurelius.titan.diskstorage.infinispan; import java.util.Iterator; import javax.annotation.Nullable; import javax.transaction.TransactionManager; import org.infinispan.Cache; import org.infinispan.manager.EmbeddedCacheManager; import com.google.common.base.Predicate; import com.google.common.collect.Iterators; import com.thinkaurelius.titan.diskstorage.StaticBuffer; import com.thinkaurelius.titan.diskstorage.StorageException; import com.thinkaurelius.titan.diskstorage.keycolumnvalue.StoreTransaction; import com.thinkaurelius.titan.diskstorage.keycolumnvalue.keyvalue.CacheStore; import com.thinkaurelius.titan.diskstorage.keycolumnvalue.keyvalue.CacheUpdateException; import com.thinkaurelius.titan.diskstorage.keycolumnvalue.keyvalue.KeySelector; import com.thinkaurelius.titan.diskstorage.keycolumnvalue.keyvalue.KeyValueEntry; import com.thinkaurelius.titan.diskstorage.util.RecordIterator; /** * @author Matthias Broecheler (me@matthiasb.com) */ public class InfinispanCacheStore implements CacheStore { private final String shortName; // private final EmbeddedCacheManager manager; protected final Cache<StaticBuffer,StaticBuffer> cache; protected final TransactionManager tm; public InfinispanCacheStore(String fullName, String shortName, EmbeddedCacheManager manager) { this.shortName = shortName; // this.manager = manager; cache = manager.getCache(fullName); tm = cache.getAdvancedCache().getTransactionManager(); } @Override public void replace(StaticBuffer key, StaticBuffer newValue, StaticBuffer oldValue, StoreTransaction txh) throws StorageException { // TODO simplify this if possible without violating the method contract if (null == newValue) { if (!cache.remove(key, oldValue)) { throw new CacheUpdateException("key=" + key + " oldValue=" + oldValue + " newValue=" + newValue); } } else if (null == oldValue) { if (null != cache.putIfAbsent(key, newValue)) { throw new CacheUpdateException("key=" + key + " oldValue=" + oldValue + " newValue=" + newValue); } } else { assert null != newValue; assert null != oldValue; if (!cache.replace(key, oldValue, newValue)) { throw new CacheUpdateException("key=" + key + " oldValue=" + oldValue + " newValue=" + newValue); } } } @Override public RecordIterator<KeyValueEntry> getKeys(final KeySelector selector, StoreTransaction txh) throws StorageException { final Iterator<StaticBuffer> keys = Iterators.filter(cache.keySet().iterator(), new Predicate<StaticBuffer>() { @Override public boolean apply(@Nullable StaticBuffer key) { return selector.include(key) && !selector.reachedLimit(); } }); return new RecordIterator<KeyValueEntry>() { @Override public boolean hasNext() { return keys.hasNext(); } @Override public KeyValueEntry next() { StaticBuffer key = keys.next(); return new KeyValueEntry(key, cache.get(key)); } @Override public void close() { // nothing to do } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public synchronized void clearStore() { cache.clear(); } @Override public void delete(StaticBuffer key, StoreTransaction txh) throws StorageException { cache.remove(key); } @Override public StaticBuffer get(StaticBuffer key, StoreTransaction txh) throws StorageException { return cache.get(key); } @Override public boolean containsKey(StaticBuffer key, StoreTransaction txh) throws StorageException { return cache.containsKey(key); } @Override public void acquireLock(StaticBuffer key, StaticBuffer expectedValue, StoreTransaction txh) throws StorageException { //Unsupported, or supported through transactions } @Override public StaticBuffer[] getLocalKeyPartition() throws StorageException { throw new UnsupportedOperationException(); } @Override public String getName() { return shortName; } @Override public void close() throws StorageException { //Do nothing } }