@Override public void mutateMany(Map<ByteBuffer, Mutation> mutations, TransactionHandle txh) throws StorageException { // null txh means a Transaction is calling this method if (null != txh) { // non-null txh -> make sure locks are valid AstyanaxTransaction atxh = (AstyanaxTransaction) txh; if (!atxh.isMutationStarted()) { // This is the first mutate call in the transaction atxh.mutationStarted(); // Verify all blind lock claims now atxh.verifyAllLockClaims(); // throws GSE and unlocks everything on any lock failure } } MutationBatch m = keyspace .prepareMutationBatch() .setConsistencyLevel(writeLevel) .withRetryPolicy(retryPolicy.duplicate()); final long delTS = TimestampProvider.getApproxNSSinceEpoch(false); final long addTS = TimestampProvider.getApproxNSSinceEpoch(true); for (Map.Entry<ByteBuffer, Mutation> ent : mutations.entrySet()) { // The CLMs for additions and deletions are separated because // Astyanax's operation timestamp cannot be set on a per-delete // or per-addition basis. ColumnListMutation<ByteBuffer> dels = m.withRow(cf, ent.getKey()); dels.setTimestamp(delTS); ColumnListMutation<ByteBuffer> adds = m.withRow(cf, ent.getKey()); adds.setTimestamp(addTS); Mutation titanMutation = ent.getValue(); if (titanMutation.hasDeletions()) { for (ByteBuffer b : titanMutation.getDeletions()) { dels.deleteColumn(b); } } if (titanMutation.hasAdditions()) { for (Entry e : titanMutation.getAdditions()) { adds.putColumn(e.getColumn(), e.getValue(), null); } } } try { m.execute(); } catch (ConnectionException e) { throw new TemporaryStorageException(e); } }
@Override public void mutateMany(Map<String, Map<ByteBuffer, Mutation>> batch, StoreTransaction txh) throws StorageException { MutationBatch m = keyspaceContext .getEntity() .prepareMutationBatch() .setConsistencyLevel(getTx(txh).getWriteConsistencyLevel().getAstyanaxConsistency()) .withRetryPolicy(retryPolicy.duplicate()); final long delTS = TimeUtility.getApproxNSSinceEpoch(false); final long addTS = TimeUtility.getApproxNSSinceEpoch(true); for (Map.Entry<String, Map<ByteBuffer, Mutation>> batchentry : batch.entrySet()) { String storeName = batchentry.getKey(); Preconditions.checkArgument( openStores.containsKey(storeName), "Store cannot be found: " + storeName); ColumnFamily<ByteBuffer, ByteBuffer> columnFamily = openStores.get(storeName).getColumnFamily(); Map<ByteBuffer, Mutation> mutations = batchentry.getValue(); for (Map.Entry<ByteBuffer, Mutation> ent : mutations.entrySet()) { // The CLMs for additions and deletions are separated because // Astyanax's operation timestamp cannot be set on a per-delete // or per-addition basis. ColumnListMutation<ByteBuffer> dels = m.withRow(columnFamily, ent.getKey()); dels.setTimestamp(delTS); ColumnListMutation<ByteBuffer> adds = m.withRow(columnFamily, ent.getKey()); adds.setTimestamp(addTS); Mutation titanMutation = ent.getValue(); if (titanMutation.hasDeletions()) { for (ByteBuffer b : titanMutation.getDeletions()) { dels.deleteColumn(b); } } if (titanMutation.hasAdditions()) { for (Entry e : titanMutation.getAdditions()) { adds.putColumn(e.getColumn(), e.getValue(), null); } } } } try { m.execute(); } catch (ConnectionException e) { throw new TemporaryStorageException(e); } }
@Override public ByteBuffer get(ByteBuffer key, ByteBuffer column, TransactionHandle txh) throws StorageException { try { OperationResult<Column<ByteBuffer>> result = keyspace .prepareQuery(cf) .setConsistencyLevel(readLevel) .withRetryPolicy(retryPolicy.duplicate()) .getKey(key) .getColumn(column) .execute(); return result.getResult().getByteBufferValue(); } catch (NotFoundException e) { return null; } catch (ConnectionException e) { throw new TemporaryStorageException(e); } }
@Override public boolean containsKey(ByteBuffer key, TransactionHandle txh) throws StorageException { try { // See getSlice() below for a warning suppression justification @SuppressWarnings("rawtypes") RowQuery rq = (RowQuery) keyspace .prepareQuery(cf) .withRetryPolicy(retryPolicy.duplicate()) .setConsistencyLevel(readLevel) .getKey(key); @SuppressWarnings("unchecked") OperationResult<ColumnList<ByteBuffer>> r = rq.withColumnRange(EMPTY, EMPTY, false, 1).execute(); return 0 < r.getResult().size(); } catch (ConnectionException e) { throw new TemporaryStorageException(e); } }
@Override public String getConfigurationProperty(final String key) throws StorageException { try { ensureColumnFamilyExists(SYSTEM_PROPERTIES_CF, "org.apache.cassandra.db.marshal.UTF8Type"); OperationResult<Column<String>> result = keyspaceContext .getEntity() .prepareQuery(PROPERTIES_CF) .setConsistencyLevel(ConsistencyLevel.CL_QUORUM) .withRetryPolicy(retryPolicy.duplicate()) .getKey(SYSTEM_PROPERTIES_KEY) .getColumn(key) .execute(); return result.getResult().getStringValue(); } catch (NotFoundException e) { return null; } catch (ConnectionException e) { throw new PermanentStorageException(e); } }
@Override public List<Entry> getSlice( ByteBuffer key, ByteBuffer columnStart, ByteBuffer columnEnd, int limit, TransactionHandle txh) throws StorageException { /* * The following hideous cast dance avoids a type-erasure error in the * RowQuery<K, V> type that emerges when K=V=ByteBuffer. Specifically, * these two methods erase to the same signature after generic reduction * during compilation: * * RowQuery<K, C> withColumnRange(C startColumn, C endColumn, boolean * reversed, int count) RowQuery<K, C> withColumnRange(ByteBuffer * startColumn, ByteBuffer endColumn, boolean reversed, int count) * * * The compiler substitutes ByteBuffer=C for both startColumn and * endColumn, compares it to its identical twin with that type * hard-coded, and dies. * * Here's the compiler error I received when attempting to compile this * code without the following casts. I used Oracle JDK 6 Linux x86_64. * * AstyanaxOrderedKeyColumnValueStore.java:[108,4] reference to * withColumnRange is ambiguous, both method * withColumnRange(C,C,boolean,int) in * com.netflix.astyanax.query.RowQuery<java.nio.ByteBuffer,java.nio.ByteBuffer> * and method * withColumnRange(java.nio.ByteBuffer,java.nio.ByteBuffer,boolean,int) * in * com.netflix.astyanax.query.RowQuery<java.nio.ByteBuffer,java.nio.ByteBuffer> * match * */ @SuppressWarnings("rawtypes") RowQuery rq = (RowQuery) keyspace .prepareQuery(cf) .setConsistencyLevel(readLevel) .withRetryPolicy(retryPolicy.duplicate()) .getKey(key); // RowQuery<ByteBuffer, ByteBuffer> rq = keyspace.prepareQuery(cf).getKey(key); rq.withColumnRange(columnStart, columnEnd, false, limit + 1); OperationResult<ColumnList<ByteBuffer>> r; try { @SuppressWarnings("unchecked") OperationResult<ColumnList<ByteBuffer>> tmp = (OperationResult<ColumnList<ByteBuffer>>) rq.execute(); r = tmp; } catch (ConnectionException e) { throw new TemporaryStorageException(e); } List<Entry> result = new ArrayList<Entry>(r.getResult().size()); int i = 0; for (Column<ByteBuffer> c : r.getResult()) { ByteBuffer colName = c.getName(); if (colName.equals(columnEnd)) { break; } result.add(new Entry(colName, c.getByteBufferValue())); if (++i == limit) { break; } } return result; }