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