private Integer seekToSubColumn( CFMetaData metadata, FileDataInput file, ByteBuffer sblockId, List<IndexHelper.IndexInfo> indexList) throws IOException { file.readInt(); // column count /* get the various column ranges we have to read */ AbstractType comparator = metadata.comparator; int index = IndexHelper.indexFor(sblockId, indexList, comparator, false); if (index == indexList.size()) return null; IndexHelper.IndexInfo indexInfo = indexList.get(index); if (comparator.compare(sblockId, indexInfo.firstName) < 0) return null; FileMark mark = file.mark(); FileUtils.skipBytesFully(file, indexInfo.offset); while (file.bytesPastMark(mark) < indexInfo.offset + indexInfo.width) { Integer dataLength = isSubBlockFound(metadata, file, sblockId); if (dataLength == null) return null; if (dataLength < 0) continue; return dataLength; } return null; }
/** * Checks if the current column is the one we are looking for * * @param metadata * @param file * @param sblockId * @return if > 0 the length to read from current file offset. if -1 not relevent. if null out of * bounds */ private Integer isSubBlockFound(CFMetaData metadata, FileDataInput file, ByteBuffer sblockId) throws IOException { ByteBuffer name = ByteBufferUtil.readWithShortLength(file); // Stop if we've gone too far (return null) if (metadata.comparator.compare(name, sblockId) > 0) return null; // verify column type; int b = file.readUnsignedByte(); // skip ts (since we know block ids are unique) long ts = file.readLong(); int sblockLength = file.readInt(); if (!name.equals(sblockId) || (b & ColumnSerializer.DELETION_MASK) != 0 || (b & ColumnSerializer.EXPIRATION_MASK) != 0) { FileUtils.skipBytesFully(file, sblockLength); return -1; } return sblockLength; }