package voldemort.store;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import voldemort.server.storage.KeyLockHandle;
import voldemort.utils.ClosableIterator;
import voldemort.utils.Pair;
import voldemort.versioning.Occurred;
import voldemort.versioning.Versioned;
public class AbstractStorageEngine<K, V, T> extends AbstractStore<K, V, T> implements
StorageEngine<K, V, T> {
public AbstractStorageEngine(String name) {
super(name);
}
@Override
public ClosableIterator<Pair<K, Versioned<V>>> entries() {
return null;
}
@Override
public ClosableIterator<K> keys() {
return null;
}
@Override
public ClosableIterator<Pair<K, Versioned<V>>> entries(int partitionId) {
return null;
}
@Override
public ClosableIterator<K> keys(int partitionId) {
return null;
}
@Override
public void truncate() {}
@Override
public boolean isPartitionAware() {
return false;
}
@Override
public boolean isPartitionScanSupported() {
return false;
}
@Override
public boolean beginBatchModifications() {
return false;
}
@Override
public List<Versioned<V>> multiVersionPut(K key, List<Versioned<V>> values) {
KeyLockHandle<V> handle = null;
try {
handle = getAndLock(key);
List<Versioned<V>> obsoleteVals = resolveAndConstructVersionsToPersist(handle.getValues(),
values);
putAndUnlock(key, handle);
return obsoleteVals;
} catch(UnsupportedOperationException uoe) {
throw new UnsupportedOperationException("multiVersionPut is not supported for "
+ this.getClass().getName());
} catch(PersistenceFailureException pfe) {
throw pfe;
} finally {
if(handle != null && !handle.isClosed()) {
releaseLock(handle);
}
}
}
@Override
public boolean endBatchModifications() {
return false;
}
/**
* Computes the final list of versions to be stored, on top of what is
* currently being stored. Final list is valuesInStorage modified in place
*
*
* @param valuesInStorage list of versions currently in storage
* @param multiPutValues list of new versions being written to storage
* @return list of versions from multiPutVals that were rejected as obsolete
*/
protected List<Versioned<V>> resolveAndConstructVersionsToPersist(List<Versioned<V>> valuesInStorage,
List<Versioned<V>> multiPutValues) {
List<Versioned<V>> obsoleteVals = new ArrayList<Versioned<V>>(multiPutValues.size());
// Go over all the values and determine whether the version is
// acceptable
for(Versioned<V> value: multiPutValues) {
Iterator<Versioned<V>> iter = valuesInStorage.iterator();
boolean obsolete = false;
// Compare the current version with a set of accepted versions
while(iter.hasNext()) {
Versioned<V> curr = iter.next();
Occurred occurred = value.getVersion().compare(curr.getVersion());
if(occurred == Occurred.BEFORE) {
obsolete = true;
break;
} else if(occurred == Occurred.AFTER) {
iter.remove();
}
}
if(obsolete) {
// add to return value if obsolete
obsoleteVals.add(value);
} else {
// else update the set of accepted versions
valuesInStorage.add(value);
}
}
return obsoleteVals;
}
@Override
public KeyLockHandle<V> getAndLock(K key) {
throw new UnsupportedOperationException("getAndLock is not supported for "
+ this.getClass().getName());
}
@Override
public void putAndUnlock(K key, KeyLockHandle<V> handle) {
throw new UnsupportedOperationException("putAndUnlock is not supported for "
+ this.getClass().getName());
}
@Override
public void releaseLock(KeyLockHandle<V> handle) {
throw new UnsupportedOperationException("releaseLock is not supported for "
+ this.getClass().getName());
}
}