Search in sources :

Example 11 with Versioned

use of voldemort.versioning.Versioned 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 12 with Versioned

use of voldemort.versioning.Versioned in project voldemort by voldemort.

the class RocksDbStorageEngine method getValueForKey.

private List<Versioned<byte[]>> getValueForKey(ByteArray key, byte[] transforms) throws PersistenceFailureException {
    long startTimeNs = -1;
    if (logger.isTraceEnabled())
        startTimeNs = System.nanoTime();
    List<Versioned<byte[]>> value = null;
    try {
        byte[] result = getRocksDB().get(storeHandle, key.get());
        if (result != null) {
            value = StoreBinaryFormat.fromByteArray(result);
        } else {
            return Collections.emptyList();
        }
    } catch (RocksDBException e) {
        logger.error(e);
        throw new PersistenceFailureException(e);
    } finally {
        if (logger.isTraceEnabled()) {
            logger.trace("Completed GET (" + getName() + ") from key " + key + " (keyRef: " + System.identityHashCode(key) + ") in " + (System.nanoTime() - startTimeNs) + " ns at " + System.currentTimeMillis());
        }
    }
    return value;
}
Also used : RocksDBException(org.rocksdb.RocksDBException) Versioned(voldemort.versioning.Versioned) PersistenceFailureException(voldemort.store.PersistenceFailureException)

Example 13 with Versioned

use of voldemort.versioning.Versioned in project voldemort by voldemort.

the class RocksDbStorageEngine method delete.

@Override
public boolean delete(ByteArray key, Version version) throws PersistenceFailureException {
    StoreUtils.assertValidKey(key);
    long startTimeNs = -1;
    if (logger.isTraceEnabled())
        startTimeNs = System.nanoTime();
    synchronized (this.locks.lockFor(key.get())) {
        try {
            byte[] value = getRocksDB().get(storeHandle, key.get());
            if (value == null) {
                return false;
            }
            if (version == null) {
                // unversioned delete. Just blow away the whole thing
                getRocksDB().remove(storeHandle, key.get());
                return true;
            } else {
                // versioned deletes; need to determine what to delete
                List<Versioned<byte[]>> vals = StoreBinaryFormat.fromByteArray(value);
                Iterator<Versioned<byte[]>> iter = vals.iterator();
                int numVersions = vals.size();
                int numDeletedVersions = 0;
                // supplied version
                while (iter.hasNext()) {
                    Versioned<byte[]> curr = iter.next();
                    Version currentVersion = curr.getVersion();
                    if (currentVersion.compare(version) == Occurred.BEFORE) {
                        iter.remove();
                        numDeletedVersions++;
                    }
                }
                if (numDeletedVersions < numVersions) {
                    // we still have some valid versions
                    value = StoreBinaryFormat.toByteArray(vals);
                    getRocksDB().put(storeHandle, key.get(), value);
                } else {
                    // we have deleted all the versions; so get rid of the
                    // entry
                    // in the database
                    getRocksDB().remove(storeHandle, key.get());
                }
                return numDeletedVersions > 0;
            }
        } catch (RocksDBException e) {
            logger.error(e);
            throw new PersistenceFailureException(e);
        } finally {
            if (logger.isTraceEnabled()) {
                logger.trace("Completed DELETE (" + getName() + ") of key " + ByteUtils.toHexString(key.get()) + " (keyRef: " + System.identityHashCode(key) + ") in " + (System.nanoTime() - startTimeNs) + " ns at " + System.currentTimeMillis());
            }
        }
    }
}
Also used : RocksDBException(org.rocksdb.RocksDBException) Versioned(voldemort.versioning.Versioned) Version(voldemort.versioning.Version) PersistenceFailureException(voldemort.store.PersistenceFailureException)

Example 14 with Versioned

use of voldemort.versioning.Versioned in project voldemort by voldemort.

the class RocksDbStorageEngine method multiVersionPut.

@Override
public List<Versioned<byte[]>> multiVersionPut(ByteArray key, List<Versioned<byte[]>> values) {
    // TODO Implement getandLock() and putAndUnlock() and then remove this
    // method
    StoreUtils.assertValidKey(key);
    long startTimeNs = -1;
    if (logger.isTraceEnabled())
        startTimeNs = System.nanoTime();
    List<Versioned<byte[]>> currentValues = null;
    List<Versioned<byte[]>> obsoleteVals = null;
    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.
             */
        try {
            byte[] result = getRocksDB().get(storeHandle, key.get());
            if (result != null) {
                currentValues = StoreBinaryFormat.fromByteArray(result);
            } else {
                currentValues = new ArrayList<Versioned<byte[]>>();
            }
        } catch (RocksDBException e) {
            logger.error(e);
            throw new PersistenceFailureException(e);
        }
        obsoleteVals = resolveAndConstructVersionsToPersist(currentValues, values);
        try {
            getRocksDB().put(storeHandle, key.get(), StoreBinaryFormat.toByteArray(currentValues));
        } catch (RocksDBException e) {
            logger.error(e);
            throw new PersistenceFailureException(e);
        } finally {
            if (logger.isTraceEnabled()) {
                String valueStr = "";
                for (Versioned<byte[]> val : currentValues) {
                    valueStr += val + ",";
                }
                logger.trace("Completed PUT (" + getName() + ") to key " + key + " (keyRef: " + System.identityHashCode(key) + " values " + valueStr + " in " + (System.nanoTime() - startTimeNs) + " ns at " + System.currentTimeMillis());
            }
        }
    }
    return obsoleteVals;
}
Also used : RocksDBException(org.rocksdb.RocksDBException) Versioned(voldemort.versioning.Versioned) PersistenceFailureException(voldemort.store.PersistenceFailureException)

Example 15 with Versioned

use of voldemort.versioning.Versioned in project voldemort by voldemort.

the class RedirectingStore method redirectingPut.

/**
     * This is slightly different from other redirecting*** methods in that,
     * this updates the remote proxy node, with this put request, so we can
     * switch back to the old cluster topology if needed
     * 
     * @param key
     * @param value
     * @param transforms
     * @throws VoldemortException
     */
private void redirectingPut(ByteArray key, Versioned<byte[]> value, byte[] transforms) throws VoldemortException {
    Cluster currentCluster = metadata.getCluster();
    // TODO:refactor O(n) linear lookup of storedef here. Ideally should be
    // a hash lookup.
    StoreDefinition storeDef = metadata.getStoreDef(getName());
    /*
         * defensively, error out if this is a read-only store and someone is
         * doing puts against it. We don't to do extra work and fill the log
         * with errors in that case.
         */
    if (storeDef.getType().compareTo(ReadOnlyStorageConfiguration.TYPE_NAME) == 0) {
        throw new UnsupportedOperationException("put() not supported on read-only store");
    }
    BaseStoreRoutingPlan currentRoutingPlan = new BaseStoreRoutingPlan(currentCluster, storeDef);
    Integer redirectNode = getProxyNode(currentRoutingPlan, storeDef, key.get());
    /**
         * If I am rebalancing for this key, try to do remote get() if this node
         * does not have the key , put it locally first to get the correct
         * version ignoring any {@link ObsoleteVersionException}
         */
    if (redirectNode != null) {
        /*
             * first check if the key exists locally. If so, it means, it has
             * been moved over (either by a proxy fetch or background fetch) and
             * we are good simply issuing the put on top of that.
             */
        List<Versioned<byte[]>> vals = getInnerStore().get(key, transforms);
        if (vals.isEmpty()) {
            // if not, then go proxy fetch it
            if (logger.isTraceEnabled()) {
                logger.trace("Proxying GET (before PUT) on stealer:" + metadata.getNodeId() + " for  key " + ByteUtils.toHexString(key.get()) + " to node:" + redirectNode);
            }
            proxyGetAndLocalPut(key, redirectNode, transforms);
        }
    }
    // Here we are sure that the current node has caught up with the proxy
    // for this key. Moving on to the put logic.
    // put the data locally, if this step fails, there will be no proxy puts
    getInnerStore().put(key, value, transforms);
    // OVE). So do not send proxy puts in those cases.
    if (redirectNode != null && !currentRoutingPlan.getReplicationNodeList(key.get()).contains(redirectNode)) {
        AsyncProxyPutTask asyncProxyPutTask = new AsyncProxyPutTask(this, key, value, transforms, redirectNode);
        proxyPutStats.reportProxyPutSubmission();
        proxyPutWorkerPool.submit(asyncProxyPutTask);
    }
}
Also used : Versioned(voldemort.versioning.Versioned) StoreDefinition(voldemort.store.StoreDefinition) Cluster(voldemort.cluster.Cluster) BaseStoreRoutingPlan(voldemort.routing.BaseStoreRoutingPlan)

Aggregations

Versioned (voldemort.versioning.Versioned)214 ByteArray (voldemort.utils.ByteArray)130 Test (org.junit.Test)88 VectorClock (voldemort.versioning.VectorClock)73 ArrayList (java.util.ArrayList)56 VoldemortException (voldemort.VoldemortException)48 List (java.util.List)36 StoreDefinition (voldemort.store.StoreDefinition)29 HashMap (java.util.HashMap)28 IOException (java.io.IOException)27 Node (voldemort.cluster.Node)27 Pair (voldemort.utils.Pair)25 Slop (voldemort.store.slop.Slop)22 ObsoleteVersionException (voldemort.versioning.ObsoleteVersionException)22 Map (java.util.Map)21 Cluster (voldemort.cluster.Cluster)17 AbstractByteArrayStoreTest (voldemort.store.AbstractByteArrayStoreTest)15 InvalidMetadataException (voldemort.store.InvalidMetadataException)13 PersistenceFailureException (voldemort.store.PersistenceFailureException)13 Version (voldemort.versioning.Version)13