@@ -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
0 commit comments