use of voldemort.versioning.Occurred in project voldemort by voldemort.
the class RocksDbStorageEngine method put.
@Override
public void put(ByteArray key, Versioned<byte[]> value, byte[] transforms) throws PersistenceFailureException {
StoreUtils.assertValidKey(key);
long startTimeNs = -1;
if (logger.isTraceEnabled())
startTimeNs = System.nanoTime();
synchronized (this.locks.lockFor(key.get())) {
/*
* Get the existing values. Make sure to "get" from the underlying
* storage instead of using the get method described in this class.
* Invoking the get method from this class will unnecessarily double
* prefix the key in case of PartitionPrefixedRocksdbStorageEngine
* and can cause unpredictable results.
*/
List<Versioned<byte[]>> currentValues;
try {
byte[] result = getRocksDB().get(storeHandle, key.get());
if (result != null) {
currentValues = StoreBinaryFormat.fromByteArray(result);
} else {
currentValues = Collections.emptyList();
}
} catch (RocksDBException e) {
logger.error(e);
throw new PersistenceFailureException(e);
}
if (currentValues.size() > 0) {
// compare vector clocks and throw out old ones, for updates
Iterator<Versioned<byte[]>> iter = currentValues.iterator();
while (iter.hasNext()) {
Versioned<byte[]> curr = iter.next();
Occurred occurred = value.getVersion().compare(curr.getVersion());
if (occurred == Occurred.BEFORE) {
throw new ObsoleteVersionException("Key " + new String(hexCodec.encode(key.get())) + " " + value.getVersion().toString() + " is obsolete, it is no greater than the current version of " + curr.getVersion().toString() + ".");
} else if (occurred == Occurred.AFTER) {
iter.remove();
}
}
} else {
// if value does not exist add the value from put request to
// existing values
currentValues = new ArrayList<Versioned<byte[]>>(1);
}
currentValues.add(value);
try {
getRocksDB().put(storeHandle, key.get(), StoreBinaryFormat.toByteArray(currentValues));
} catch (RocksDBException e) {
logger.error(e);
throw new PersistenceFailureException(e);
} finally {
if (logger.isTraceEnabled()) {
logger.trace("Completed PUT (" + getName() + ") to key " + key + " (keyRef: " + System.identityHashCode(key) + " value " + value + " in " + (System.nanoTime() - startTimeNs) + " ns at " + System.currentTimeMillis());
}
}
}
}
use of voldemort.versioning.Occurred in project voldemort by voldemort.
the class KratiStorageEngine method put.
@Override
public void put(ByteArray key, Versioned<byte[]> value, byte[] transforms) throws VoldemortException {
StoreUtils.assertValidKey(key);
synchronized (this.locks.lockFor(key.get())) {
// First get the value
List<Versioned<byte[]>> existingValuesList = this.get(key, null);
// If no value, add one
if (existingValuesList.size() == 0) {
existingValuesList = new ArrayList<Versioned<byte[]>>();
existingValuesList.add(new Versioned<byte[]>(value.getValue(), value.getVersion()));
} else {
// Update the value
List<Versioned<byte[]>> removedValueList = new ArrayList<Versioned<byte[]>>();
for (Versioned<byte[]> versioned : existingValuesList) {
Occurred occurred = value.getVersion().compare(versioned.getVersion());
if (occurred == Occurred.BEFORE)
throw new ObsoleteVersionException("Obsolete version for key '" + key + "': " + value.getVersion());
else if (occurred == Occurred.AFTER)
removedValueList.add(versioned);
}
existingValuesList.removeAll(removedValueList);
existingValuesList.add(value);
}
try {
datastore.put(key.get(), assembleValues(existingValuesList));
} catch (Exception e) {
String message = "Failed to put key " + key;
logger.error(message, e);
throw new VoldemortException(message, e);
}
}
}
use of voldemort.versioning.Occurred in project voldemort by voldemort.
the class MysqlStorageEngine method put.
@Override
public void put(ByteArray key, Versioned<byte[]> value, byte[] transforms) throws PersistenceFailureException {
StoreUtils.assertValidKey(key);
boolean doCommit = false;
Connection conn = null;
PreparedStatement insert = null;
PreparedStatement select = null;
ResultSet results = null;
String insertSql = "insert into " + getName() + " (key_, version_, value_) values (?, ?, ?)";
String selectSql = "select version_ from " + getName() + " where key_ = ?";
try {
conn = datasource.getConnection();
conn.setAutoCommit(false);
// check for superior versions
select = conn.prepareStatement(selectSql);
select.setBytes(1, key.get());
results = select.executeQuery();
while (results.next()) {
VectorClock version = new VectorClock(results.getBytes("version_"));
Occurred occurred = value.getVersion().compare(version);
if (occurred == Occurred.BEFORE)
throw new ObsoleteVersionException("Attempt to put version " + value.getVersion() + " which is superceeded by " + version + ".");
else if (occurred == Occurred.AFTER)
delete(conn, key.get(), version.toBytes());
}
// Okay, cool, now put the value
insert = conn.prepareStatement(insertSql);
insert.setBytes(1, key.get());
VectorClock clock = (VectorClock) value.getVersion();
insert.setBytes(2, clock.toBytes());
insert.setBytes(3, value.getValue());
insert.executeUpdate();
doCommit = true;
} catch (SQLException e) {
if (e.getErrorCode() == MYSQL_ERR_DUP_KEY || e.getErrorCode() == MYSQL_ERR_DUP_ENTRY) {
throw new ObsoleteVersionException("Key or value already used.");
} else {
throw new PersistenceFailureException("Fix me!", e);
}
} finally {
if (conn != null) {
try {
if (doCommit)
conn.commit();
else
conn.rollback();
} catch (SQLException e) {
}
}
tryClose(results);
tryClose(insert);
tryClose(select);
tryClose(conn);
}
}
use of voldemort.versioning.Occurred in project voldemort by voldemort.
the class InMemoryStorageEngine method put.
@Override
public synchronized void put(K key, Versioned<V> value, T transforms) throws VoldemortException {
StoreUtils.assertValidKey(key);
List<Versioned<V>> items = map.get(key);
// If we have no value, add the current value
if (items == null) {
items = new ArrayList<Versioned<V>>();
}
// Check for existing versions - remember which items to
// remove in case of success
List<Versioned<V>> itemsToRemove = new ArrayList<Versioned<V>>(items.size());
for (Versioned<V> versioned : items) {
Occurred occurred = value.getVersion().compare(versioned.getVersion());
if (occurred == Occurred.BEFORE) {
throw new ObsoleteVersionException("Obsolete version for key '" + key + "': " + value.getVersion());
} else if (occurred == Occurred.AFTER) {
itemsToRemove.add(versioned);
}
}
items.removeAll(itemsToRemove);
items.add(value);
map.put(key, items);
}
use of voldemort.versioning.Occurred in project voldemort by voldemort.
the class ReadRepairer method singleKeyGetRepairs.
private List<NodeValue<K, V>> singleKeyGetRepairs(List<NodeValue<K, V>> nodeValues) {
int size = nodeValues.size();
if (size <= 1)
return Collections.emptyList();
// 1. Create a multi-map of nodes to their existing Versions
Multimap<Integer, NodeValue<K, V>> nodeVersionsMap = HashMultimap.create();
for (NodeValue<K, V> nodeValue : nodeValues) {
nodeVersionsMap.put(nodeValue.getNodeId(), nodeValue);
}
// 2. Create a map of the final set of versions (for this key)
Map<Version, NodeValue<K, V>> mostCurrentVersionsMap = new HashMap<Version, NodeValue<K, V>>();
// Initialize with the first element from the input
mostCurrentVersionsMap.put(nodeValues.get(0).getVersion(), nodeValues.get(0));
// check each value against the current set of most current versions
for (int i = 1; i < nodeValues.size(); i++) {
NodeValue<K, V> curr = nodeValues.get(i);
boolean concurrentToAll = true;
/*
* Make a copy for the traversal. This is because the original map
* can be modified during this traversal
*/
Set<Version> knownGoodVersions = new HashSet<Version>(mostCurrentVersionsMap.keySet());
for (Version currentGoodversion : knownGoodVersions) {
// If the version already exists, do nothing
if (curr.getVersion().equals(currentGoodversion)) {
concurrentToAll = false;
if (logger.isDebugEnabled()) {
logger.debug("Version already exists in the most current set: " + curr);
}
break;
}
// Check the ordering of the current value
Occurred occurred = curr.getVersion().compare(currentGoodversion);
if (occurred == Occurred.BEFORE) {
// This value is obsolete! Break from the loop
if (logger.isDebugEnabled()) {
logger.debug("Version is obsolete : " + curr);
}
concurrentToAll = false;
break;
} else if (occurred == Occurred.AFTER) {
// This concurrent value is obsolete and the current value
// should replace it
mostCurrentVersionsMap.remove(currentGoodversion);
concurrentToAll = false;
mostCurrentVersionsMap.put(curr.getVersion(), curr);
if (logger.isDebugEnabled()) {
logger.debug("Updating the current best - adding : " + curr);
}
}
}
// to the concurrent set
if (concurrentToAll) {
mostCurrentVersionsMap.put(curr.getVersion(), curr);
if (logger.isDebugEnabled()) {
logger.debug("Value is concurrent to all ! : " + curr);
}
}
}
// 3. Compare 1 and 2 and create the repair list
List<NodeValue<K, V>> repairs = new ArrayList<NodeValue<K, V>>(3);
for (int nodeId : nodeVersionsMap.keySet()) {
Set<Version> finalVersions = new HashSet<Version>(mostCurrentVersionsMap.keySet());
if (logger.isDebugEnabled()) {
logger.debug("Set of final versions = " + finalVersions);
}
// Calculate the set difference between final Versions and
// the versions currently existing for nodeId
Set<Version> currentNodeVersions = new HashSet<Version>();
for (NodeValue<K, V> nodeValue : nodeVersionsMap.get(nodeId)) {
currentNodeVersions.add(nodeValue.getVersion());
}
finalVersions.removeAll(currentNodeVersions);
if (logger.isDebugEnabled()) {
logger.debug("Remaining versions to be repaired for this node after the set difference = " + finalVersions);
}
// Repair nodeId with the remaining Versioned values
for (Version remainingVersion : finalVersions) {
NodeValue<K, V> repair = new NodeValue<K, V>(nodeId, mostCurrentVersionsMap.get(remainingVersion).getKey(), mostCurrentVersionsMap.get(remainingVersion).getVersioned());
if (logger.isDebugEnabled()) {
logger.debug("Node value marked to be repaired : " + repair);
}
repairs.add(repair);
}
}
return repairs;
}
Aggregations