Skip to content

Commit 68d2784

Browse files
committed
optimize tsid ordinal loading
1 parent e32d986 commit 68d2784

File tree

2 files changed

+96
-12
lines changed

2 files changed

+96
-12
lines changed

server/src/main/java/org/elasticsearch/index/codec/tsdb/es819/ES819TSDBDocValuesProducer.java

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,20 +1328,104 @@ public void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs
13281328
public void loadBlock(BlockLoader.TSIDOrdinalsBuilder builder, BlockLoader.Docs docs, int offset)
13291329
throws IOException {
13301330
assert maxOrd >= 0;
1331-
for (int i = offset; i < docs.count(); i++) {
1332-
int index = docs.get(i);
1333-
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1334-
final int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1335-
if (blockIndex != currentBlockIndex) {
1336-
assert blockIndex > currentBlockIndex : blockIndex + " < " + currentBlockIndex;
1337-
// no need to seek if the loading block is the next block
1338-
if (currentBlockIndex + 1 != blockIndex) {
1339-
valuesData.seek(indexReader.get(blockIndex));
1331+
doc = docs.get(docs.count() - 1);
1332+
boolean isDense = doc - docs.get(0) == docs.count() - 1;
1333+
if (isDense) {
1334+
// Figure out where we start and whether the previous block needs to be read:
1335+
int firstDocId = docs.get(offset);
1336+
int firstBlockIndex = firstDocId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1337+
int firstBlockInIndex = firstDocId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1338+
1339+
int start;
1340+
if (currentBlockIndex != firstBlockIndex) {
1341+
// different block, so seek:
1342+
valuesData.seek(indexReader.get(firstBlockIndex));
1343+
if (firstBlockInIndex == 0) {
1344+
// start is a full block, defer consuming later with complete blocks.
1345+
start = offset;
1346+
} else {
1347+
// partial block, consume it here
1348+
currentBlockIndex = firstBlockInIndex;
1349+
decoder.decodeOrdinals(valuesData, currentBlock, bitsPerOrd);
1350+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - firstBlockInIndex;
1351+
if (docs.count() < length) {
1352+
builder.appendOrds(currentBlock, firstBlockInIndex, docs.count());
1353+
return;
1354+
} else {
1355+
builder.appendOrds(currentBlock, firstBlockInIndex, length);
1356+
start = offset + length;
1357+
}
1358+
}
1359+
} else {
1360+
// consume remaining
1361+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - firstBlockInIndex;
1362+
if (docs.count() < length) {
1363+
builder.appendOrds(currentBlock, firstBlockInIndex, docs.count());
1364+
return;
1365+
} else {
1366+
builder.appendOrds(currentBlock, firstBlockInIndex, length);
1367+
start = offset + length;
1368+
}
1369+
}
1370+
1371+
// Figure out how many complete blocks we can read:
1372+
int completeBlockSize = 0;
1373+
int[] completeBlocks = new int[(docs.count() / ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE) + 1];
1374+
int docsIndex = start;
1375+
while (docsIndex < docs.count()) {
1376+
int docId = docs.get(docsIndex);
1377+
if (docsIndex + ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE >= docs.count()) {
1378+
break;
13401379
}
1341-
currentBlockIndex = blockIndex;
1380+
1381+
int nextIndex = docs.get(docsIndex + ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE);
1382+
if (nextIndex - docId == ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE) {
1383+
completeBlocks[completeBlockSize++] = docId;
1384+
docsIndex += ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE;
1385+
} else {
1386+
break;
1387+
}
1388+
}
1389+
1390+
// Read those complete blocks:
1391+
for (int i = 0; i < completeBlockSize; i++) {
1392+
int docId = completeBlocks[i];
1393+
currentBlockIndex = docId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
13421394
decoder.decodeOrdinals(valuesData, currentBlock, bitsPerOrd);
1395+
int blockInIndex = docId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1396+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - blockInIndex;
1397+
assert length == ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE : "unexpected length [" + length + "]";
1398+
builder.appendOrds(currentBlock, blockInIndex, length);
1399+
}
1400+
1401+
// Check for a remainder and if so read it:
1402+
if (docsIndex < docs.count()) {
1403+
int docId = docs.get(docsIndex);
1404+
currentBlockIndex = docId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1405+
decoder.decodeOrdinals(valuesData, currentBlock, bitsPerOrd);
1406+
1407+
int blockInIndex = docId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1408+
int lastBlockInIndex = doc & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1409+
int length = lastBlockInIndex - blockInIndex + 1;
1410+
1411+
builder.appendOrds(currentBlock, blockInIndex, length);
1412+
}
1413+
} else {
1414+
for (int i = offset; i < docs.count(); i++) {
1415+
int index = docs.get(i);
1416+
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1417+
final int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1418+
if (blockIndex != currentBlockIndex) {
1419+
assert blockIndex > currentBlockIndex : blockIndex + " < " + currentBlockIndex;
1420+
// no need to seek if the loading block is the next block
1421+
if (currentBlockIndex + 1 != blockIndex) {
1422+
valuesData.seek(indexReader.get(blockIndex));
1423+
}
1424+
currentBlockIndex = blockIndex;
1425+
decoder.decodeOrdinals(valuesData, currentBlock, bitsPerOrd);
1426+
}
1427+
builder.appendOrd(Math.toIntExact(currentBlock[blockInIndex]));
13431428
}
1344-
builder.appendOrd(Math.toIntExact(currentBlock[blockInIndex]));
13451429
}
13461430
}
13471431

test/framework/src/main/java/org/elasticsearch/index/mapper/TestBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ public BlockLoader.TSIDOrdinalsBuilder appendOrd(long value) {
287287
@Override
288288
public BlockLoader.TSIDOrdinalsBuilder appendOrds(long[] values, int from, int length) {
289289
try {
290-
System.arraycopy(values, from, ords, expectedCount, length);
290+
System.arraycopy(values, from, ords, count, length);
291291
} catch (ArrayIndexOutOfBoundsException e) {
292292
throw e;
293293
}

0 commit comments

Comments
 (0)