private IColumn validateAndGetColumn(List<Row> rows, ByteBuffer columnName) throws NotFoundException { if (rows.isEmpty()) throw new NotFoundException(); if (rows.size() > 1) throw new RuntimeException("Block id returned more than one row"); Row row = rows.get(0); if (row.cf == null) throw new NotFoundException(); IColumn col = row.cf.getColumn(columnName); if (col == null || !col.isLive()) throw new NotFoundException(); return col; }
private LocalOrRemoteBlock getRemoteSubBlock( ByteBuffer blockId, ByteBuffer sblockId, int offset, ColumnParent subBlockDataPath) throws TimedOutException, UnavailableException, InvalidRequestException, NotFoundException { // The column name is the SubBlock id (UUID) ReadCommand rc = new SliceByNamesReadCommand( cfsKeyspace, blockId, subBlockDataPath, Arrays.asList(sblockId)); try { // CL=ONE as there are NOT multiple versions of the blocks. List<Row> rows = StorageProxy.read(Arrays.asList(rc), ConsistencyLevel.ONE); IColumn col = null; try { col = validateAndGetColumn(rows, sblockId); } catch (NotFoundException e) { // This is a best effort to get the value. Sometimes due to the size of // the sublocks, the normal replication may time out leaving a replicate without // the piece of data. Hence we re try with higher CL. rows = StorageProxy.read(Arrays.asList(rc), ConsistencyLevel.QUORUM); } col = validateAndGetColumn(rows, sblockId); ByteBuffer value = col.value(); if (value.remaining() < offset) throw new InvalidRequestException("Invalid offset for block of size: " + value.remaining()); LocalOrRemoteBlock block = new LocalOrRemoteBlock(); if (offset > 0) { ByteBuffer offsetBlock = value.duplicate(); offsetBlock.position(offsetBlock.position() + offset); block.setRemote_block(offsetBlock); } else { block.setRemote_block(value); } return block; } catch (IOException e) { throw new RuntimeException(e); } catch (TimeoutException e) { throw new TimedOutException(); } }