@@ -237,6 +237,8 @@ private static void unpackLoop64(MemorySegment buf, int bitWidth, int offset, lo
237237 long blockByteStride = 128L * bitWidth ;
238238 for (int block = 0 ; block < blockCount ; block ++, blockByteOff += blockByteStride ) {
239239 int blockLogicStart = block * 1024 - offset ;
240+ boolean fullBlock = blockLogicStart >= 0 && (long ) blockLogicStart + 1023L < rowCount ;
241+
240242 for (int row = 0 ; row < 64 ; row ++) {
241243 int currWord = (row * bitWidth ) / 64 ;
242244 int nextWord = ((row + 1 ) * bitWidth ) / 64 ;
@@ -247,24 +249,46 @@ private static void unpackLoop64(MemorySegment buf, int bitWidth, int offset, lo
247249 int s = row % 8 ;
248250 int baseIdx = blockLogicStart + FL_ORDER [o ] * 16 + s * 128 ;
249251 long wordBase = blockByteOff + (long ) lanes * currWord * 8 ;
250- long hiBase = (remainingBits > 0 ) ? blockByteOff + (long ) lanes * nextWord * 8 : 0L ;
251- long loMask = (remainingBits > 0 ) ? (1L << currentBits ) - 1L : 0L ;
252- long hiMask = (remainingBits > 0 ) ? (1L << remainingBits ) - 1L : 0L ;
253- for (int lane = 0 ; lane < lanes ; lane ++) {
254- int logicalIdx = baseIdx + lane ;
255- if (logicalIdx < 0 || logicalIdx >= rowCount ) {
256- continue ;
257- }
258- long src = buf .get (LE_LONG , wordBase + (long ) lane * 8 );
259- long value ;
252+
253+ if (fullBlock ) {
254+ long outBase = (long ) baseIdx * 8 ;
260255 if (remainingBits > 0 ) {
261- long lo = (src >>> shift ) & loMask ;
262- long hi = buf .get (LE_LONG , hiBase + (long ) lane * 8 ) & hiMask ;
263- value = lo | (hi << currentBits );
256+ long hiBase = blockByteOff + (long ) lanes * nextWord * 8 ;
257+ long loMask = (1L << currentBits ) - 1L ;
258+ long hiMask = (1L << remainingBits ) - 1L ;
259+ long laneOff = 0L ;
260+ for (int lane = 0 ; lane < lanes ; lane ++, laneOff += 8L ) {
261+ long lo = (buf .get (LE_LONG , wordBase + laneOff ) >>> shift ) & loMask ;
262+ long hi = buf .get (LE_LONG , hiBase + laneOff ) & hiMask ;
263+ out .set (LE_LONG , outBase + laneOff , lo | (hi << currentBits ));
264+ }
264265 } else {
265- value = (src >>> shift ) & bitMask ;
266+ long laneOff = 0L ;
267+ for (int lane = 0 ; lane < lanes ; lane ++, laneOff += 8L ) {
268+ out .set (LE_LONG , outBase + laneOff ,
269+ (buf .get (LE_LONG , wordBase + laneOff ) >>> shift ) & bitMask );
270+ }
271+ }
272+ } else {
273+ long hiBase = (remainingBits > 0 ) ? blockByteOff + (long ) lanes * nextWord * 8 : 0L ;
274+ long loMask = (remainingBits > 0 ) ? (1L << currentBits ) - 1L : 0L ;
275+ long hiMask = (remainingBits > 0 ) ? (1L << remainingBits ) - 1L : 0L ;
276+ for (int lane = 0 ; lane < lanes ; lane ++) {
277+ int logicalIdx = baseIdx + lane ;
278+ if (logicalIdx < 0 || logicalIdx >= rowCount ) {
279+ continue ;
280+ }
281+ long src = buf .get (LE_LONG , wordBase + (long ) lane * 8 );
282+ long value ;
283+ if (remainingBits > 0 ) {
284+ long lo = (src >>> shift ) & loMask ;
285+ long hi = buf .get (LE_LONG , hiBase + (long ) lane * 8 ) & hiMask ;
286+ value = lo | (hi << currentBits );
287+ } else {
288+ value = (src >>> shift ) & bitMask ;
289+ }
290+ out .set (LE_LONG , (long ) logicalIdx * 8 , value );
266291 }
267- out .set (LE_LONG , (long ) logicalIdx * 8 , value );
268292 }
269293 }
270294 }
0 commit comments