Search in sources :

Example 1 with Location

use of com.basho.riak.client.core.query.Location in project YCSB by brianfrankcooper.

the class RiakKVClient method update.

/**
   * Update a record in the database. Any field/value pairs in the specified values HashMap will be written into the
   * record with the specified record key, overwriting any existing values with the same field name.
   *
   * @param table  The name of the table (Riak bucket)
   * @param key    The record key of the record to write.
   * @param values A HashMap of field/value pairs to update in the record
   * @return Zero on success, a non-zero error code on error
   */
@Override
public Status update(String table, String key, HashMap<String, ByteIterator> values) {
    // If eventual consistency model is in use, then an update operation is pratically equivalent to an insert one.
    if (!strongConsistency) {
        return insert(table, key, values);
    }
    Location location = new Location(new Namespace(bucketType, table), key);
    UpdateValue update = new UpdateValue.Builder(location).withUpdate(new UpdateEntity(new RiakObject().setValue(BinaryValue.create(serializeTable(values))))).build();
    RiakFuture<UpdateValue.Response, Location> future = riakClient.executeAsync(update);
    try {
        // For some reason, the update transaction doesn't throw any exception when no cluster has been started, so one
        // needs to check whether it was done or not. When calling the wasUpdated() function with no nodes available, a
        // NullPointerException is thrown.
        // Moreover, such exception could be thrown when more threads are trying to update the same key or, more
        // generally, when the system is being queried by many clients (i.e. overloaded). This is a known limitation of
        // Riak KV's strong consistency implementation.
        future.get(transactionTimeLimit, TimeUnit.SECONDS).wasUpdated();
    } catch (TimeoutException e) {
        if (debug) {
            System.err.println("Unable to update key " + key + ". Reason: TIME OUT");
        }
        return TIME_OUT;
    } catch (Exception e) {
        if (debug) {
            System.err.println("Unable to update key " + key + ". Reason: " + e.toString());
        }
        return Status.ERROR;
    }
    return Status.OK;
}
Also used : RiakObject(com.basho.riak.client.core.query.RiakObject) UpdateValue(com.basho.riak.client.api.commands.kv.UpdateValue) Namespace(com.basho.riak.client.core.query.Namespace) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) Location(com.basho.riak.client.core.query.Location) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with Location

use of com.basho.riak.client.core.query.Location in project YCSB by brianfrankcooper.

the class RiakKVClient method insert.

/**
   * Insert a record in the database. Any field/value pairs in the specified values HashMap will be written into the
   * record with the specified record key. Also creates a secondary index (2i) for each record consisting of the key
   * converted to long to be used for the scan operation.
   *
   * @param table  The name of the table (Riak bucket)
   * @param key    The record key of the record to insert.
   * @param values A HashMap of field/value pairs to insert in the record
   * @return Zero on success, a non-zero error code on error
   */
@Override
public Status insert(String table, String key, HashMap<String, ByteIterator> values) {
    Location location = new Location(new Namespace(bucketType, table), key);
    RiakObject object = new RiakObject();
    // riak.bucket_type property.
    if (strongConsistency && performStrongConsistentScans) {
        // Create a fake object to store in the default bucket-type just to keep track of the 2i indices.
        Location fakeLocation = new Location(new Namespace(strongConsistentScansBucketType, table), key);
        // Obviously, we want the fake object to contain as less data as possible. We can't create a void object, so
        // we have to choose the minimum data size allowed: it is one byte.
        RiakObject fakeObject = new RiakObject();
        fakeObject.setValue(BinaryValue.create(new byte[] { 0x00 }));
        fakeObject.getIndexes().getIndex(LongIntIndex.named("key_int")).add(getKeyAsLong(key));
        StoreValue fakeStore = new StoreValue.Builder(fakeObject).withLocation(fakeLocation).build();
        // We don't mind whether the operation is finished or not, because waiting for it to complete would slow down the
        // client and make our solution too heavy to be seen as a valid compromise. This will obviously mean that under
        // heavy load conditions a scan operation could fail due to an unfinished "fakeStore".
        riakClient.executeAsync(fakeStore);
    } else if (!strongConsistency) {
        // The next operation is useless when using strong consistency model, so it's ok to perform it only when using
        // eventual consistency.
        object.getIndexes().getIndex(LongIntIndex.named("key_int")).add(getKeyAsLong(key));
    }
    // Store proper values into the object.
    object.setValue(BinaryValue.create(serializeTable(values)));
    StoreValue store = new StoreValue.Builder(object).withOption(StoreValue.Option.W, wvalue).withLocation(location).build();
    RiakFuture<StoreValue.Response, Location> future = riakClient.executeAsync(store);
    try {
        future.get(transactionTimeLimit, TimeUnit.SECONDS);
    } catch (TimeoutException e) {
        if (debug) {
            System.err.println("Unable to insert key " + key + ". Reason: TIME OUT");
        }
        return TIME_OUT;
    } catch (Exception e) {
        if (debug) {
            System.err.println("Unable to insert key " + key + ". Reason: " + e.toString());
        }
        return Status.ERROR;
    }
    return Status.OK;
}
Also used : RiakObject(com.basho.riak.client.core.query.RiakObject) StoreValue(com.basho.riak.client.api.commands.kv.StoreValue) Namespace(com.basho.riak.client.core.query.Namespace) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) Location(com.basho.riak.client.core.query.Location) TimeoutException(java.util.concurrent.TimeoutException)

Example 3 with Location

use of com.basho.riak.client.core.query.Location in project YCSB by brianfrankcooper.

the class RiakKVClient method scan.

/**
   * Perform a range scan for a set of records in the database. Each field/value pair from the result will be stored in
   * a HashMap.
   * Note: The scan operation requires the use of secondary indexes (2i) and LevelDB.
   *
   * @param table       The name of the table (Riak bucket)
   * @param startkey    The record key of the first record to read.
   * @param recordcount The number of records to read
   * @param fields      The list of fields to read, or null for all of them
   * @param result      A Vector of HashMaps, where each HashMap is a set field/value pairs for one record
   * @return Zero on success, a non-zero error code on error
   */
@Override
public Status scan(String table, String startkey, int recordcount, Set<String> fields, Vector<HashMap<String, ByteIterator>> result) {
    if (strongConsistency && !performStrongConsistentScans) {
        return Status.NOT_IMPLEMENTED;
    }
    // The strong consistent bucket-type is not capable of storing 2i indexes. So, we need to read them from the fake
    // one (which we use only to store indexes). This is why, when using such a consistency model, the bucketType2i
    // variable is set to FAKE_BUCKET_TYPE.
    IntIndexQuery iiq = new IntIndexQuery.Builder(new Namespace(bucketType2i, table), "key", getKeyAsLong(startkey), Long.MAX_VALUE).withMaxResults(recordcount).withPaginationSort(true).build();
    Location location;
    RiakFuture<IntIndexQuery.Response, IntIndexQuery> future = riakClient.executeAsync(iiq);
    try {
        IntIndexQuery.Response response = future.get(transactionTimeLimit, TimeUnit.SECONDS);
        List<IntIndexQuery.Response.Entry> entries = response.getEntries();
        // If no entries were retrieved, then something bad happened...
        if (entries.size() == 0) {
            if (debug) {
                System.err.println("Unable to scan any record starting from key " + startkey + ", aborting transaction. " + "Reason: NOT FOUND");
            }
            return Status.NOT_FOUND;
        }
        for (IntIndexQuery.Response.Entry entry : entries) {
            // fetching the key from the one retrieved with the 2i indexes search operation.
            if (strongConsistency) {
                location = new Location(new Namespace(bucketType, table), entry.getRiakObjectLocation().getKeyAsString());
            } else {
                location = entry.getRiakObjectLocation();
            }
            FetchValue fv = new FetchValue.Builder(location).withOption(FetchValue.Option.R, rvalue).build();
            FetchValue.Response keyResponse = fetch(fv);
            if (keyResponse.isNotFound()) {
                if (debug) {
                    System.err.println("Unable to scan all requested records starting from key " + startkey + ", aborting " + "transaction. Reason: NOT FOUND");
                }
                return Status.NOT_FOUND;
            }
            // Create the partial result to add to the result vector.
            HashMap<String, ByteIterator> partialResult = new HashMap<>();
            createResultHashMap(fields, keyResponse, partialResult);
            result.add(partialResult);
        }
    } catch (TimeoutException e) {
        if (debug) {
            System.err.println("Unable to scan all requested records starting from key " + startkey + ", aborting " + "transaction. Reason: TIME OUT");
        }
        return TIME_OUT;
    } catch (Exception e) {
        if (debug) {
            System.err.println("Unable to scan all records starting from key " + startkey + ", aborting transaction. " + "Reason: " + e.toString());
        }
        return Status.ERROR;
    }
    return Status.OK;
}
Also used : RiakUtils.createResultHashMap(com.yahoo.ycsb.db.riak.RiakUtils.createResultHashMap) IntIndexQuery(com.basho.riak.client.api.commands.indexes.IntIndexQuery) Namespace(com.basho.riak.client.core.query.Namespace) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) FetchValue(com.basho.riak.client.api.commands.kv.FetchValue) Location(com.basho.riak.client.core.query.Location) TimeoutException(java.util.concurrent.TimeoutException)

Example 4 with Location

use of com.basho.riak.client.core.query.Location in project YCSB by brianfrankcooper.

the class RiakKVClient method delete.

/**
   * Delete a record from the database.
   *
   * @param table The name of the table (Riak bucket)
   * @param key   The record key of the record to delete.
   * @return Zero on success, a non-zero error code on error
   */
@Override
public Status delete(String table, String key) {
    Location location = new Location(new Namespace(bucketType, table), key);
    DeleteValue dv = new DeleteValue.Builder(location).build();
    RiakFuture<Void, Location> future = riakClient.executeAsync(dv);
    try {
        future.get(transactionTimeLimit, TimeUnit.SECONDS);
    } catch (TimeoutException e) {
        if (debug) {
            System.err.println("Unable to delete key " + key + ". Reason: TIME OUT");
        }
        return TIME_OUT;
    } catch (Exception e) {
        if (debug) {
            System.err.println("Unable to delete key " + key + ". Reason: " + e.toString());
        }
        return Status.ERROR;
    }
    return Status.OK;
}
Also used : DeleteValue(com.basho.riak.client.api.commands.kv.DeleteValue) Namespace(com.basho.riak.client.core.query.Namespace) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) Location(com.basho.riak.client.core.query.Location) TimeoutException(java.util.concurrent.TimeoutException)

Example 5 with Location

use of com.basho.riak.client.core.query.Location in project YCSB by brianfrankcooper.

the class RiakKVClient method read.

/**
   * Read a record from the database. Each field/value pair from the result will be stored in a HashMap.
   *
   * @param table  The name of the table (Riak bucket)
   * @param key    The record key of the record to read.
   * @param fields The list of fields to read, or null for all of them
   * @param result A HashMap of field/value pairs for the result
   * @return Zero on success, a non-zero error code on error
   */
@Override
public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
    Location location = new Location(new Namespace(bucketType, table), key);
    FetchValue fv = new FetchValue.Builder(location).withOption(FetchValue.Option.R, rvalue).build();
    FetchValue.Response response;
    try {
        response = fetch(fv);
        if (response.isNotFound()) {
            if (debug) {
                System.err.println("Unable to read key " + key + ". Reason: NOT FOUND");
            }
            return Status.NOT_FOUND;
        }
    } catch (TimeoutException e) {
        if (debug) {
            System.err.println("Unable to read key " + key + ". Reason: TIME OUT");
        }
        return TIME_OUT;
    } catch (Exception e) {
        if (debug) {
            System.err.println("Unable to read key " + key + ". Reason: " + e.toString());
        }
        return Status.ERROR;
    }
    // Create the result HashMap.
    createResultHashMap(fields, response, result);
    return Status.OK;
}
Also used : FetchValue(com.basho.riak.client.api.commands.kv.FetchValue) Namespace(com.basho.riak.client.core.query.Namespace) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) Location(com.basho.riak.client.core.query.Location) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

Location (com.basho.riak.client.core.query.Location)5 Namespace (com.basho.riak.client.core.query.Namespace)5 IOException (java.io.IOException)5 TimeoutException (java.util.concurrent.TimeoutException)5 FetchValue (com.basho.riak.client.api.commands.kv.FetchValue)2 RiakObject (com.basho.riak.client.core.query.RiakObject)2 IntIndexQuery (com.basho.riak.client.api.commands.indexes.IntIndexQuery)1 DeleteValue (com.basho.riak.client.api.commands.kv.DeleteValue)1 StoreValue (com.basho.riak.client.api.commands.kv.StoreValue)1 UpdateValue (com.basho.riak.client.api.commands.kv.UpdateValue)1 RiakUtils.createResultHashMap (com.yahoo.ycsb.db.riak.RiakUtils.createResultHashMap)1