/**
   * Read the data stored with the unique row. This data is normally a 'foreign' key to another
   * column family.
   *
   * @return
   * @throws Exception
   */
  public ByteBuffer readData() throws Exception {
    ColumnList<C> result =
        keyspace
            .prepareQuery(columnFamily)
            .setConsistencyLevel(consistencyLevel)
            .getKey(key)
            .execute()
            .getResult();

    boolean hasColumn = false;
    ByteBuffer data = null;
    for (Column<C> column : result) {
      if (column.getTtl() == 0) {
        if (hasColumn) {
          throw new IllegalStateException("Row has multiple uniquneness locks");
        }
        hasColumn = true;
        data = column.getByteBufferValue();
      }
    }

    if (!hasColumn) {
      throw new NotFoundException(this.key.toString() + " has no uniquness lock");
    }
    return data;
  }
  @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;
  }