use of com.thinkaurelius.titan.diskstorage.PermanentStorageException in project titan by thinkaurelius.
the class AstyanaxOrderedKeyColumnValueStore method getKeys.
@Override
public KeyIterator getKeys(KeyRangeQuery query, StoreTransaction txh) throws StorageException {
// this query could only be done when byte-ordering partitioner is used
// because Cassandra operates on tokens internally which means that even contiguous
// range of keys (e.g. time slice) with random partitioner could produce disjoint set of tokens
// returning ambiguous results to the user.
Partitioner partitioner = storeManager.getPartitioner();
if (partitioner != Partitioner.BYTEORDER)
throw new PermanentStorageException("getKeys(KeyRangeQuery could only be used with byte-ordering partitioner.");
ByteBuffer start = query.getKeyStart().asByteBuffer(), end = query.getKeyEnd().asByteBuffer();
int limit = (query.hasLimit()) ? query.getLimit() : Integer.MAX_VALUE;
RowSliceQuery rowSlice = keyspace.prepareQuery(columnFamily).setConsistencyLevel(getTx(txh).getReadConsistencyLevel().getAstyanaxConsistency()).withRetryPolicy(retryPolicy.duplicate()).getKeyRange(start, end, null, null, Integer.MAX_VALUE);
// Astyanax is bad at builder pattern :(
rowSlice.withColumnRange(query.getSliceStart().asByteBuffer(), query.getSliceEnd().asByteBuffer(), false, limit);
// Omit final the query's keyend from the result, if present in result
final Rows<ByteBuffer, ByteBuffer> r;
try {
r = ((OperationResult<Rows<ByteBuffer, ByteBuffer>>) rowSlice.execute()).getResult();
} catch (ConnectionException e) {
throw new TemporaryStorageException(e);
}
Iterator<Row<ByteBuffer, ByteBuffer>> i = Iterators.filter(r.iterator(), new KeySkipPredicate(query.getKeyEnd().asByteBuffer()));
return new RowIterator(i, query);
}
use of com.thinkaurelius.titan.diskstorage.PermanentStorageException in project titan by thinkaurelius.
the class AstyanaxOrderedKeyColumnValueStore method getKeys.
@Override
public KeyIterator getKeys(@Nullable SliceQuery sliceQuery, StoreTransaction txh) throws StorageException {
if (storeManager.getPartitioner() != Partitioner.RANDOM)
throw new PermanentStorageException("This operation is only allowed when random partitioner (md5 or murmur3) is used.");
AllRowsQuery allRowsQuery = keyspace.prepareQuery(columnFamily).getAllRows();
if (sliceQuery != null) {
int limit = (sliceQuery.hasLimit()) ? sliceQuery.getLimit() : Integer.MAX_VALUE;
allRowsQuery.withColumnRange(sliceQuery.getSliceStart().asByteBuffer(), sliceQuery.getSliceEnd().asByteBuffer(), false, limit);
}
Rows<ByteBuffer, ByteBuffer> result;
try {
/* Note: we need to fetch columns for each row as well to remove "range ghosts" */
OperationResult op = // pre-fetch that many rows at a time
allRowsQuery.setRowLimit(storeManager.getPageSize()).setConcurrencyLevel(// one execution thread for fetching portion of rows
1).setExceptionCallback(new ExceptionCallback() {
private int retries = 0;
@Override
public boolean onException(ConnectionException e) {
try {
// make 3 re-tries
return retries > 2;
} finally {
retries++;
}
}
}).execute();
result = ((OperationResult<Rows<ByteBuffer, ByteBuffer>>) op).getResult();
} catch (ConnectionException e) {
throw new PermanentStorageException(e);
}
return new RowIterator(result.iterator(), sliceQuery);
}
use of com.thinkaurelius.titan.diskstorage.PermanentStorageException in project titan by thinkaurelius.
the class CassandraEmbeddedKeyColumnValueStore method getSlice.
@Override
public List<Entry> getSlice(KeySliceQuery query, StoreTransaction txh) throws StorageException {
QueryPath slicePath = new QueryPath(columnFamily);
ReadCommand sliceCmd = new SliceFromReadCommand(// Keyspace name
keyspace, // Row key
query.getKey().asByteBuffer(), // ColumnFamily
slicePath, // Start column name (empty means begin at first result)
query.getSliceStart().asByteBuffer(), // End column name (empty means max out the count)
query.getSliceEnd().asByteBuffer(), // Reverse results? (false=no)
false, // Max count of Columns to return
query.getLimit());
List<Row> slice = read(sliceCmd, getTx(txh).getReadConsistencyLevel().getDBConsistency());
if (null == slice || 0 == slice.size())
return new ArrayList<Entry>(0);
int sliceSize = slice.size();
if (1 < sliceSize)
throw new PermanentStorageException("Received " + sliceSize + " rows for single key");
Row r = slice.get(0);
if (null == r) {
log.warn("Null Row object retrieved from Cassandra StorageProxy");
return new ArrayList<Entry>(0);
}
ColumnFamily cf = r.cf;
if (null == cf) {
log.debug("null ColumnFamily (\"{}\")", columnFamily);
return new ArrayList<Entry>(0);
}
if (cf.isMarkedForDelete())
return new ArrayList<Entry>(0);
return cfToEntries(cf, query.getSliceEnd());
}
use of com.thinkaurelius.titan.diskstorage.PermanentStorageException in project titan by thinkaurelius.
the class CassandraEmbeddedKeyColumnValueStore method cfToEntries.
private List<Entry> cfToEntries(ColumnFamily cf, StaticBuffer columnEnd) throws StorageException {
assert !cf.isMarkedForDelete();
Collection<IColumn> columns = cf.getSortedColumns();
List<Entry> result = new ArrayList<Entry>(columns.size());
/*
* We want to call columnEnd.equals() on column name ByteBuffers in the
* loop below. But columnEnd is a StaticBuffer, and it doesn't have an
* equals() method that accepts ByteBuffer. We create a ByteBuffer copy
* of columnEnd just for equals() comparisons in the for loop below.
*
* TODO remove this if StaticBuffer's equals() accepts ByteBuffer
*/
ByteBuffer columnEndBB = columnEnd.asByteBuffer();
// Populate Entries into return collection
for (IColumn icol : columns) {
if (null == icol)
throw new PermanentStorageException("Unexpected null IColumn");
if (icol.isMarkedForDelete())
continue;
ByteBuffer name = org.apache.cassandra.utils.ByteBufferUtil.clone(icol.name());
ByteBuffer value = org.apache.cassandra.utils.ByteBufferUtil.clone(icol.value());
if (columnEndBB.equals(name))
continue;
result.add(new ByteBufferEntry(name, value));
}
return result;
}
use of com.thinkaurelius.titan.diskstorage.PermanentStorageException in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testDeleteLocksSkipsToNextLockOnPermanentStorageException.
/**
* Same as
* {@link #testDeleteLocksSkipsToNextLockAfterMaxTemporaryStorageExceptions()}
* , except instead of exceeding the temporary exception retry count on a
* lock, that lock throws a single permanent exception.
*
* @throws StorageException shoudn't happen
*/
@Test
public void testDeleteLocksSkipsToNextLockOnPermanentStorageException() throws StorageException {
ConsistentKeyLockStatus defaultLS = makeStatusNow();
currentTimeNS++;
expect(lockState.getLocksForTx(defaultTx)).andReturn(Maps.newLinkedHashMap(ImmutableMap.of(defaultLockID, defaultLS)));
List<StaticBuffer> dels = ImmutableList.of(codec.toLockCol(defaultLS.getWriteTimestamp(TimeUnit.NANOSECONDS), defaultLockRid));
expect(times.getApproxNSSinceEpoch()).andReturn(currentTimeNS);
store.mutate(eq(defaultLockKey), eq(ImmutableList.<Entry>of()), eq(dels), eq(defaultTx));
expectLastCall().andThrow(new PermanentStorageException("Storage cluster has been destroyed by a tornado"));
expect(mediator.unlock(defaultLockID, defaultTx)).andReturn(true);
// lockState.release(defaultTx, defaultLockID);
ctrl.replay();
locker.deleteLocks(defaultTx);
}
Aggregations