Search in sources :

Example 1 with Occurred

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());
            }
        }
    }
}
Also used : RocksDBException(org.rocksdb.RocksDBException) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) Versioned(voldemort.versioning.Versioned) PersistenceFailureException(voldemort.store.PersistenceFailureException) Occurred(voldemort.versioning.Occurred)

Example 2 with Occurred

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);
        }
    }
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) Versioned(voldemort.versioning.Versioned) ArrayList(java.util.ArrayList) VoldemortException(voldemort.VoldemortException) Occurred(voldemort.versioning.Occurred) ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) VoldemortException(voldemort.VoldemortException) IOException(java.io.IOException)

Example 3 with Occurred

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);
    }
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) SQLException(java.sql.SQLException) VectorClock(voldemort.versioning.VectorClock) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) PersistenceFailureException(voldemort.store.PersistenceFailureException) Occurred(voldemort.versioning.Occurred)

Example 4 with Occurred

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);
}
Also used : ObsoleteVersionException(voldemort.versioning.ObsoleteVersionException) Versioned(voldemort.versioning.Versioned) ArrayList(java.util.ArrayList) Occurred(voldemort.versioning.Occurred)

Example 5 with Occurred

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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Version(voldemort.versioning.Version) Occurred(voldemort.versioning.Occurred) HashSet(java.util.HashSet)

Aggregations

Occurred (voldemort.versioning.Occurred)7 ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)5 Versioned (voldemort.versioning.Versioned)5 ArrayList (java.util.ArrayList)4 PersistenceFailureException (voldemort.store.PersistenceFailureException)3 DatabaseEntry (com.sleepycat.je.DatabaseEntry)1 DatabaseException (com.sleepycat.je.DatabaseException)1 OperationStatus (com.sleepycat.je.OperationStatus)1 Transaction (com.sleepycat.je.Transaction)1 IOException (java.io.IOException)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 RocksDBException (org.rocksdb.RocksDBException)1 VoldemortException (voldemort.VoldemortException)1 AsyncOperationStatus (voldemort.server.protocol.admin.AsyncOperationStatus)1 VectorClock (voldemort.versioning.VectorClock)1