@@ -38,31 +38,34 @@ static long expected(long origin, float average, int index) {
38
38
return origin + (long ) (average * (long ) index );
39
39
}
40
40
41
+ private static final int BLOCK_SIZE = Byte .SIZE ; // #bits in a block
42
+ private static final int BLOCK_BITS = 3 ; // The #bits representing BLOCK_SIZE
43
+ private static final int MOD_MASK = BLOCK_SIZE - 1 ; // x % BLOCK_SIZE
44
+
41
45
final int blockShift , blockMask ;
42
46
final long valueCount ;
43
47
final long [] minValues ;
44
48
final float [] averages ;
45
- final PackedInts . Reader [] subReaders ;
49
+ final LongValues [] subReaders ;
46
50
final long sumBPV ;
51
+ final long totalByteCount ;
47
52
48
53
/** Sole constructor. */
49
54
public static MonotonicBlockPackedReader of (
50
- IndexInput in , int packedIntsVersion , int blockSize , long valueCount , boolean direct )
51
- throws IOException {
52
- return new MonotonicBlockPackedReader (in , packedIntsVersion , blockSize , valueCount , direct );
55
+ IndexInput in , int packedIntsVersion , int blockSize , long valueCount ) throws IOException {
56
+ return new MonotonicBlockPackedReader (in , packedIntsVersion , blockSize , valueCount );
53
57
}
54
58
55
59
private MonotonicBlockPackedReader (
56
- IndexInput in , int packedIntsVersion , int blockSize , long valueCount , boolean direct )
57
- throws IOException {
60
+ IndexInput in , int packedIntsVersion , int blockSize , long valueCount ) throws IOException {
58
61
this .valueCount = valueCount ;
59
62
blockShift = checkBlockSize (blockSize , MIN_BLOCK_SIZE , MAX_BLOCK_SIZE );
60
63
blockMask = blockSize - 1 ;
61
64
final int numBlocks = numBlocks (valueCount , blockSize );
62
65
minValues = new long [numBlocks ];
63
66
averages = new float [numBlocks ];
64
- subReaders = new PackedInts . Reader [numBlocks ];
65
- long sumBPV = 0 ;
67
+ subReaders = new LongValues [numBlocks ];
68
+ long sumBPV = 0 , totalByteCount = 0 ;
66
69
for (int i = 0 ; i < numBlocks ; ++i ) {
67
70
minValues [i ] = in .readZLong ();
68
71
averages [i ] = Float .intBitsToFloat (in .readInt ());
@@ -72,24 +75,44 @@ private MonotonicBlockPackedReader(
72
75
throw new IOException ("Corrupted" );
73
76
}
74
77
if (bitsPerValue == 0 ) {
75
- subReaders [i ] = new PackedInts . NullReader ( blockSize ) ;
78
+ subReaders [i ] = LongValues . ZEROES ;
76
79
} else {
77
80
final int size = (int ) Math .min (blockSize , valueCount - (long ) i * blockSize );
78
- if (direct ) {
79
- final long pointer = in .getFilePointer ();
80
- subReaders [i ] =
81
- PackedInts .getDirectReaderNoHeader (
82
- in , PackedInts .Format .PACKED , packedIntsVersion , size , bitsPerValue );
83
- in .seek (
84
- pointer + PackedInts .Format .PACKED .byteCount (packedIntsVersion , size , bitsPerValue ));
85
- } else {
86
- subReaders [i ] =
87
- PackedInts .getReaderNoHeader (
88
- in , PackedInts .Format .PACKED , packedIntsVersion , size , bitsPerValue );
89
- }
81
+ final int byteCount =
82
+ Math .toIntExact (
83
+ PackedInts .Format .PACKED .byteCount (packedIntsVersion , size , bitsPerValue ));
84
+ totalByteCount += byteCount ;
85
+ final byte [] blocks = new byte [byteCount ];
86
+ in .readBytes (blocks , 0 , byteCount );
87
+ final long maskRight = ((1L << bitsPerValue ) - 1 );
88
+ final int bpvMinusBlockSize = bitsPerValue - BLOCK_SIZE ;
89
+ subReaders [i ] =
90
+ new LongValues () {
91
+ @ Override
92
+ public long get (long index ) {
93
+ // The abstract index in a bit stream
94
+ final long majorBitPos = index * bitsPerValue ;
95
+ // The offset of the first block in the backing byte-array
96
+ int blockOffset = (int ) (majorBitPos >>> BLOCK_BITS );
97
+ // The number of value-bits after the first byte
98
+ long endBits = (majorBitPos & MOD_MASK ) + bpvMinusBlockSize ;
99
+ if (endBits <= 0 ) {
100
+ // Single block
101
+ return ((blocks [blockOffset ] & 0xFFL ) >>> -endBits ) & maskRight ;
102
+ }
103
+ // Multiple blocks
104
+ long value = ((blocks [blockOffset ++] & 0xFFL ) << endBits ) & maskRight ;
105
+ while (endBits > BLOCK_SIZE ) {
106
+ endBits -= BLOCK_SIZE ;
107
+ value |= (blocks [blockOffset ++] & 0xFFL ) << endBits ;
108
+ }
109
+ return value | ((blocks [blockOffset ] & 0xFFL ) >>> (BLOCK_SIZE - endBits ));
110
+ }
111
+ };
90
112
}
91
113
}
92
114
this .sumBPV = sumBPV ;
115
+ this .totalByteCount = totalByteCount ;
93
116
}
94
117
95
118
@ Override
@@ -110,9 +133,7 @@ public long ramBytesUsed() {
110
133
long sizeInBytes = 0 ;
111
134
sizeInBytes += RamUsageEstimator .sizeOf (minValues );
112
135
sizeInBytes += RamUsageEstimator .sizeOf (averages );
113
- for (PackedInts .Reader reader : subReaders ) {
114
- sizeInBytes += reader .ramBytesUsed ();
115
- }
136
+ sizeInBytes += totalByteCount ;
116
137
return sizeInBytes ;
117
138
}
118
139
0 commit comments