@@ -364,47 +364,44 @@ private long insertInLong(long lastValue, int lastLength, int longIndex, int ind
364364 private void removeAndShiftAllLeft (int longIndex , int indexInLong ) {
365365 // start at the end and work back to current long index
366366 int currentLongIndex = getLongIndex (elements - 1 );
367- int leftmostBit = 0 ; // dud value for first shift
367+ long leftmostBit = 0 ; // dud value for first shift
368368 // keep adding the old MSB as LSB of the previous long index and shifting the rest to the left
369369 while (currentLongIndex > longIndex ) {
370- leftmostBit = appendBitAndRemoveAtIndex (leftmostBit , currentLongIndex --, 0 );
370+ leftmostBit = removeAtIndexAndAppend (leftmostBit , 1 , currentLongIndex --, 0 );
371371 }
372- // add the final MSB as LSB of {@code longIndex} and shift only the bits to the removed 's right
373- appendBitAndRemoveAtIndex (leftmostBit , longIndex , indexInLong );
372+ // add the final MSB as LSB of longIndex and shift only the bits to the popped bit 's right
373+ removeAtIndexAndAppend (leftmostBit , 1 , longIndex , indexInLong );
374374 }
375375
376376 /**
377- * Appends the bit at the end of the long specified by the arguments and removes the bit at {@code indexInLong}.
377+ * Removes the {@code lastLength} bits from the long specified by {@code longIndex} starting from {@code indexInLong}
378+ * and then appends the same length of bits from {@code lastValue} at the end of the long. The
378379 *
379- * <p>
380- * Since {@code indexInLong} can be at the middle of the long word, removing the bit is done by splitting the
381- * long in two parts, clearing the desired bit and shifting once to restore the order of the previous bits.
382- * </p>
383- *
384- * @param bit the bit to be appended to the long
380+ * @param lastValue bits to be appended to the long
381+ * @param lastLength length in bits of the last value
385382 * @param longIndex index of the long in the {@code data} array
386- * @param indexInLong index of the bit in the long
387- * @return bit at {@code longIndex} that was popped out
383+ * @param indexInLong index of the first removed bit in the long
384+ * @return bits that were popped from the long
388385 */
389- private int appendBitAndRemoveAtIndex ( int bit , int longIndex , int indexInLong ) {
386+ private long removeAtIndexAndAppend ( long lastValue , int lastLength , int longIndex , int indexInLong ) {
390387 // get right side [indexInLong : ], can not be empty, will be shifted
391388 long rightSide = (data [longIndex ] << indexInLong ) >>> indexInLong ;
392389 // get left side [0 : indexInLong), can be empty, will remain intact
393- long leftSide = data [longIndex ] - rightSide ;
390+ long leftSide = data [longIndex ] & ~ rightSide ;
394391
395- // save MSB
396- int rightSideMSB = getBitInLong (rightSide , indexInLong );
397- // clear MSB and shift to the left to make it "disappear"
398- rightSide &= ~ singleBitMask ( indexInLong );
399- rightSide <<= 1 ;
400- // append the previous bit
401- rightSide += bit ;
392+ // save removed values
393+ long poppedValues = selectBits (rightSide , indexInLong , lastLength ) >>> ( BITS_PER_LONG - indexInLong - lastLength );
394+
395+ // clear copied bits and shift to the left
396+ rightSide = ( rightSide << indexInLong + lastLength ) >>> indexInLong ;
397+ // append the previous bits
398+ rightSide |= lastValue ;
402399
403400 // re-join the two parts
404- data [longIndex ] = leftSide + rightSide ;
401+ data [longIndex ] = leftSide ^ rightSide ;
405402
406- // return the MSB
407- return rightSideMSB ;
403+ // return the popped bits
404+ return poppedValues ;
408405 }
409406
410407 /**
0 commit comments