Skip to content

Commit 4c1931f

Browse files
committed
More specialization for dense singleton longs.
1 parent 54843ed commit 4c1931f

File tree

8 files changed

+427
-30
lines changed

8 files changed

+427
-30
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
public abstract class BlockAwareNumericDocValues extends NumericDocValues {
1919

20-
public abstract void loadBlock(BlockLoader.LongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException;
20+
public abstract void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException;
2121

2222
public abstract void loadBlock(BlockLoader.IntBuilder builder, BlockLoader.Docs docs, int offset) throws IOException;
2323

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

Lines changed: 144 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ public long longValue() {
10721072
}
10731073

10741074
@Override
1075-
public void loadBlock(BlockLoader.LongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1075+
public void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
10761076
for (int i = offset; i < docs.count(); i++) {
10771077
builder.appendLong(0L);
10781078
}
@@ -1177,7 +1177,7 @@ public long longValue() {
11771177
}
11781178

11791179
@Override
1180-
public void loadBlock(BlockLoader.LongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1180+
public void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
11811181
for (int i = offset; i < docs.count(); i++) {
11821182
if (disi.advanceExact(docs.get(i))) {
11831183
builder.appendLong(0L);
@@ -1304,29 +1304,118 @@ private void loadCurrentBlock(int blockIndex) throws IOException {
13041304
}
13051305

13061306
@Override
1307-
public void loadBlock(BlockLoader.LongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1308-
for (int i = offset; i < docs.count(); i++) {
1309-
doc = docs.get(i);
1310-
builder.appendLong(longValue());
1311-
}
1307+
public void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1308+
assert maxOrd == -1;
1309+
doc = docs.get(docs.count() - 1);
1310+
boolean isDense = doc - docs.get(0) == docs.count() - 1;
1311+
if (isDense) {
1312+
// Figure out where we start and whether the previous block needs to be read:
1313+
int firstDocId = docs.get(offset);
1314+
int firstBlockIndex = firstDocId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1315+
int firstBlockInIndex = firstDocId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1316+
1317+
int start;
1318+
if (currentBlockIndex != firstBlockIndex) {
1319+
// different block, so seek:
1320+
valuesData.seek(indexReader.get(firstBlockIndex));
1321+
if (firstBlockInIndex == 0) {
1322+
// start is a full block, defer consuming later with complete blocks.
1323+
start = offset;
1324+
} else {
1325+
// partial block, consume it here
1326+
currentBlockIndex = firstBlockInIndex;
1327+
decoder.decode(valuesData, currentBlock);
1328+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - firstBlockInIndex;
1329+
if (docs.count() < length) {
1330+
builder.appendLongs(currentBlock, firstBlockInIndex, docs.count());
1331+
return;
1332+
} else {
1333+
builder.appendLongs(currentBlock, firstBlockInIndex, length);
1334+
start = offset + length;
1335+
}
1336+
}
1337+
} else {
1338+
// consume remaining
1339+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - firstBlockInIndex;
1340+
if (docs.count() < length) {
1341+
builder.appendLongs(currentBlock, firstBlockInIndex, docs.count());
1342+
return;
1343+
} else {
1344+
builder.appendLongs(currentBlock, firstBlockInIndex, length);
1345+
start = offset + length;
1346+
}
1347+
}
13121348

1313-
// TODO: Try to fix this:
1314-
// int startIndexInBlock = 0;
1315-
// int currentBlockIndex = docs.get(0) >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1316-
// for (int i = startIndexInBlock; i < docs.count(); i++) {
1317-
// doc = docs.get(i);
1318-
// int blockIndex = doc >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1319-
// if (blockIndex != currentBlockIndex) {
1320-
// TODO: make builder aware of codec?
1321-
// loadCurrentBlock(blockIndex);
1322-
// for (int j = startIndexInBlock; j < i; j++) {
1323-
// int blockInIndex = doc & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1324-
// builder.appendLong(currentBlock[blockInIndex]);
1325-
// }
1326-
// currentBlockIndex = blockIndex;
1327-
// startIndexInBlock = i;
1328-
// }
1329-
// }
1349+
// Figure out how many complete blocks we can read:
1350+
int completeBlockSize = 0;
1351+
int[] completeBlocks = new int[(docs.count() / ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE) + 1];
1352+
int docsIndex = start;
1353+
while (docsIndex < docs.count()) {
1354+
int docId = docs.get(docsIndex);
1355+
if (docsIndex + ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE >= docs.count()) {
1356+
break;
1357+
}
1358+
1359+
int nextIndex = docs.get(docsIndex + ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE);
1360+
if (nextIndex - docId == ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE) {
1361+
completeBlocks[completeBlockSize++] = docId;
1362+
docsIndex += ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE;
1363+
} else {
1364+
break;
1365+
}
1366+
}
1367+
1368+
// Read those complete blocks:
1369+
for (int i = 0; i < completeBlockSize; i++) {
1370+
int docId = completeBlocks[i];
1371+
currentBlockIndex = docId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1372+
decoder.decode(valuesData, currentBlock);
1373+
int blockInIndex = docId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1374+
int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - blockInIndex;
1375+
assert length == ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE : "unexpected length [" + length + "]";
1376+
builder.appendLongs(currentBlock, blockInIndex, length);
1377+
}
1378+
1379+
// Check for a remainder and if so read it:
1380+
if (docsIndex < docs.count()) {
1381+
int docId = docs.get(docsIndex);
1382+
currentBlockIndex = docId >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1383+
decoder.decode(valuesData, currentBlock);
1384+
1385+
int blockInIndex = docId & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1386+
int lastBlockInIndex = doc & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1387+
int length = lastBlockInIndex - blockInIndex + 1;
1388+
1389+
builder.appendLongs(currentBlock, blockInIndex, length);
1390+
}
1391+
// for (int i = start; i < docs.count();) {
1392+
// int index = docs.get(i);
1393+
// int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1394+
// currentBlockIndex = blockIndex;
1395+
// decoder.decode(valuesData, currentBlock);
1396+
//
1397+
// int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1398+
// int length = ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE - blockInIndex;
1399+
// builder.appendLongs(currentBlock, blockInIndex, length);
1400+
// i += length;
1401+
// }
1402+
} else {
1403+
for (int i = offset; i < docs.count(); i++) {
1404+
int index = docs.get(i);
1405+
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1406+
final int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1407+
if (blockIndex != currentBlockIndex) {
1408+
assert blockIndex > currentBlockIndex : blockIndex + " < " + currentBlockIndex;
1409+
// no need to seek if the loading block is the next block
1410+
if (currentBlockIndex + 1 != blockIndex) {
1411+
valuesData.seek(indexReader.get(blockIndex));
1412+
}
1413+
currentBlockIndex = blockIndex;
1414+
decoder.decode(valuesData, currentBlock);
1415+
}
1416+
builder.appendLong(currentBlock[blockInIndex]);
1417+
}
1418+
}
13301419
}
13311420

13321421
@Override
@@ -1358,6 +1447,7 @@ public void loadBlock(BlockLoader.IntBuilder builder, BlockLoader.Docs docs, int
13581447

13591448
@Override
13601449
public void loadBlock(BlockLoader.SingletonOrdinalsBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1450+
assert maxOrd >= 0;
13611451
for (int i = offset; i < docs.count(); i++) {
13621452
final int index = docs.get(i);
13631453
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
@@ -1383,10 +1473,23 @@ public void loadBlock(
13831473
int offset,
13841474
BlockDocValuesReader.ToDouble toDouble
13851475
) throws IOException {
1476+
assert maxOrd == -1;
13861477
for (int i = offset; i < docs.count(); i++) {
1387-
doc = docs.get(i);
1388-
builder.appendDouble(toDouble.convert(longValue()));
1478+
final int index = doc;
1479+
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1480+
final int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1481+
if (blockIndex != currentBlockIndex) {
1482+
assert blockIndex > currentBlockIndex : blockIndex + " < " + currentBlockIndex;
1483+
// no need to seek if the loading block is the next block
1484+
if (currentBlockIndex + 1 != blockIndex) {
1485+
valuesData.seek(indexReader.get(blockIndex));
1486+
}
1487+
currentBlockIndex = blockIndex;
1488+
decoder.decode(valuesData, currentBlock);
1489+
}
1490+
builder.appendDouble(toDouble.convert(currentBlock[blockInIndex]));
13891491
}
1492+
doc = docs.get(docs.count() - 1);
13901493
}
13911494

13921495
};
@@ -1452,7 +1555,7 @@ public long longValue() throws IOException {
14521555
}
14531556

14541557
@Override
1455-
public void loadBlock(BlockLoader.LongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
1558+
public void loadBlock(BlockLoader.SingletonLongBuilder builder, BlockLoader.Docs docs, int offset) throws IOException {
14561559
// TODO: collect all doc ids for current block and then append values to builder?
14571560

14581561
for (int i = offset; i < docs.count(); i++) {
@@ -1502,12 +1605,25 @@ public void loadBlock(
15021605
int offset,
15031606
BlockDocValuesReader.ToDouble toDouble
15041607
) throws IOException {
1608+
assert maxOrd == -1;
15051609
// TODO: collect all doc ids for current block and then append values to builder?
15061610

15071611
for (int i = offset; i < docs.count(); i++) {
15081612
int docId = docs.get(i);
15091613
if (disi.advanceExact(docId)) {
1510-
double value = toDouble.convert(longValue());
1614+
final int index = disi.index();
1615+
final int blockIndex = index >>> ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SHIFT;
1616+
final int blockInIndex = index & ES819TSDBDocValuesFormat.NUMERIC_BLOCK_MASK;
1617+
if (blockIndex != currentBlockIndex) {
1618+
assert blockIndex > currentBlockIndex : blockIndex + "<=" + currentBlockIndex;
1619+
// no need to seek if the loading block is the next block
1620+
if (currentBlockIndex + 1 != blockIndex) {
1621+
valuesData.seek(indexReader.get(blockIndex));
1622+
}
1623+
currentBlockIndex = blockIndex;
1624+
decoder.decode(valuesData, currentBlock);
1625+
}
1626+
double value = toDouble.convert(currentBlock[blockInIndex]);
15111627
builder.appendDouble(value);
15121628
} else {
15131629
builder.appendNull();

server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private static class BlockAwareSingletonLongs extends BlockDocValuesReader {
188188

189189
@Override
190190
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset) throws IOException {
191-
try (BlockLoader.LongBuilder builder = factory.longsFromDocValues(docs.count() - offset)) {
191+
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
192192
blockAware.loadBlock(builder, docs, offset);
193193
return builder.build();
194194
}

server/src/main/java/org/elasticsearch/index/mapper/BlockLoader.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,8 @@ interface BlockFactory {
400400
*/
401401
LongBuilder longs(int expectedCount);
402402

403+
BlockLoader.SingletonLongBuilder singletonLongs(int expectedCount);
404+
403405
/**
404406
* Build a builder to load only {@code null}s.
405407
*/
@@ -505,6 +507,13 @@ interface LongBuilder extends Builder {
505507
LongBuilder appendLong(long value);
506508
}
507509

510+
interface SingletonLongBuilder extends Builder {
511+
512+
SingletonLongBuilder appendLong(long value);
513+
514+
SingletonLongBuilder appendLongs(long[] values, int from, int length);
515+
}
516+
508517
interface SingletonOrdinalsBuilder extends Builder {
509518
/**
510519
* Appends an ordinal to the builder.

0 commit comments

Comments
 (0)