use of io.datarouter.filesystem.snapshot.block.value.ValueBlock in project datarouter by hotpads.
the class WordTests method testValueBlockV1.
@Test
public void testValueBlockV1() {
Supplier<ValueBlockV1Encoder> encoderSupplier = ValueBlockV1Encoder::new;
Ref<ValueBlockV1Encoder> encoder = new Ref<>(encoderSupplier.get());
int blockSize = 4096;
List<String> inputs = WordDataset.scanWords(getClass().getSimpleName() + "-testValueBlockV1").list();
List<byte[]> blocks = Scanner.of(inputs).map(str -> str.getBytes(StandardCharsets.UTF_8)).map(value -> new SnapshotEntry(EmptyArray.BYTE, EmptyArray.BYTE, new byte[][] { value })).concat(value -> {
encoder.get().add(value, 0);
if (encoder.get().numBytes() >= blockSize) {
byte[] block = encoder.get().encode().concat();
encoder.set(encoderSupplier.get());
return Scanner.of(block);
}
return Scanner.empty();
}).list();
if (encoder.get().numRecords() > 0) {
blocks.add(encoder.get().encode().concat());
}
logger.warn("encoded {} value blocks", blocks.size());
List<String> outputs = Scanner.of(blocks).map(ValueBlockV1::new).concat(ValueBlock::valueCopies).map(bytes -> new String(bytes, StandardCharsets.UTF_8)).list();
Require.equals(outputs.size(), inputs.size());
for (int i = 0; i < inputs.size(); ++i) {
if (ObjectTool.notEquals(outputs.get(i), inputs.get(i))) {
logger.warn("actual=[{}] expected=[{}]", outputs.get(i), inputs.get(i));
String message = String.format("actual=[%s] does not equal expected=[%s]", CsvIntByteStringCodec.INSTANCE.encode(outputs.get(i).getBytes(StandardCharsets.UTF_8)), CsvIntByteStringCodec.INSTANCE.encode(inputs.get(i).getBytes(StandardCharsets.UTF_8)));
throw new IllegalArgumentException(message);
}
}
}
use of io.datarouter.filesystem.snapshot.block.value.ValueBlock in project datarouter by hotpads.
the class SnapshotIdReader method getRecord.
public SnapshotRecord getRecord(long recordId) {
LeafBlock leafBlock = leafBlock(recordId);
Bytes key = leafBlock.snapshotKey(recordId);
Bytes value = leafBlock.snapshotValue(recordId);
int numColumns = rootBlock.numColumns();
byte[][] columnValues = new byte[numColumns][];
for (int column = 0; column < numColumns; ++column) {
ValueLocation valueLocation = leafBlock.getValueBlock(column, recordId);
BlockKey valueBlockKey = leafBlock.valueBlockKey(snapshotKey, column, valueLocation.valueBlockId);
ValueBlock valueBlock = blockLoader.value(valueBlockKey);
Bytes columnValue = valueBlock.value(valueLocation.valueIndex);
columnValues[column] = columnValue.toArray();
}
return new SnapshotRecord(recordId, key.toArray(), value.toArray(), columnValues);
}
use of io.datarouter.filesystem.snapshot.block.value.ValueBlock in project datarouter by hotpads.
the class SnapshotKeyReader method findRecord.
public Optional<SnapshotRecord> findRecord(byte[] searchKey) {
LeafBlock leafBlock = leafBlock(searchKey);
Optional<Long> optRecordId = leafBlock.findRecordId(searchKey);
if (optRecordId.isEmpty()) {
return Optional.empty();
}
long recordId = optRecordId.get();
byte[] value = leafBlock.snapshotValue(recordId).toArray();
int numColumns = rootBlock.numColumns();
byte[][] columnValues = new byte[numColumns][];
for (int column = 0; column < numColumns; ++column) {
// TODO lookup value blocks using already-found keyId
Optional<ValueLocation> optValueLocation = leafBlock.findValueBlock(column, searchKey);
if (optValueLocation.isEmpty()) {
return Optional.empty();
}
ValueLocation valueLocation = optValueLocation.get();
BlockKey valueBlockKey = leafBlock.valueBlockKey(snapshotKey, column, valueLocation.valueBlockId);
ValueBlock valueBlock = blockLoader.value(valueBlockKey);
Bytes columnValue = valueBlock.value(valueLocation.valueIndex);
columnValues[column] = columnValue.toArray();
}
return Optional.of(new SnapshotRecord(recordId, searchKey, value, columnValues));
}
use of io.datarouter.filesystem.snapshot.block.value.ValueBlock in project datarouter by hotpads.
the class LeafBlockWithValueBlocks method scan.
public Scanner<SnapshotRecord> scan(int fromRecordIdInclusive) {
return Scanner.iterate(0, recordIndex -> recordIndex + 1).limit(leafBlock.numRecords()).include(recordIndex -> leafBlock.recordId(recordIndex) >= fromRecordIdInclusive).map(recordIndex -> {
long recordId = leafBlock.firstRecordId() + recordIndex;
byte[] key = leafBlock.blockKey(recordIndex).toArray();
byte[] value = leafBlock.blockValue(recordIndex).toArray();
byte[][] columnValues = new byte[rootBlock.numColumns()][];
for (int column = 0; column < rootBlock.numColumns(); ++column) {
// TODO improve LeafBlock methods to skip looking up valueBlockOffset
int valueBlockOffset = leafBlock.valueBlockOffsetForKey(column, recordIndex);
int valueBlockId = leafBlock.firstValueBlockId(column) + valueBlockOffset;
ValueBlock valueBlock = getValueBlock(column, valueBlockId);
int valueIndex = leafBlock.valueIndex(column, valueBlockOffset, recordIndex);
columnValues[column] = valueBlock.value(valueIndex).toArray();
}
return new SnapshotRecord(recordId, key, value, columnValues);
});
}
Aggregations