private void generateBackpointerUpdates(BucketUpdate update, UpdateInstructions updateInstructions) {
        // Keep track of the previous, non-deleted Key's offset. The first one points to nothing.
        AtomicLong previousOffset = new AtomicLong(Attributes.NULL_ATTRIBUTE_VALUE);

        // Keep track of whether the previous Key has been replaced.
        AtomicBoolean previousReplaced = new AtomicBoolean(false);

        // Process all existing Keys, in order of Offsets, and either unlink them (if replaced) or update pointers as needed.
        AtomicBoolean first = new AtomicBoolean(true);
        update.getExistingKeys().stream()
              .sorted(Comparator.comparingLong(BucketUpdate.KeyInfo::getOffset))
              .forEach(keyInfo -> {
                    boolean replaced = update.isKeyUpdated(keyInfo.getKey());
                    if (replaced) {
                        // This one has been replaced or removed; delete any backpointer originating from it.
                        if (!first.get()) {
                            // ... except if this is the first one in the list, which means it doesn't have a backpointer.
                            updateInstructions.withAttribute(generateBackpointerRemoval(keyInfo.getOffset()));
                        }

                        // Record that this has been replaced.
                        updateInstructions.entryRemoved();
                        previousReplaced.set(true);
                    } else {
                        if (previousReplaced.get()) {
                            // This one hasn't been replaced or removed, however its previous one has been.
                            // Repoint it to whatever key is now ahead of it, or remove it (if previousOffset is nothing).
                            updateInstructions.withAttribute(generateBackpointerUpdate(keyInfo.getOffset(), previousOffset.get()));
                            previousReplaced.set(false);
                        }

                        previousOffset.set(keyInfo.getOffset()); // Record the last valid offset.
                    }

                    first.set(false);
                });

        // Process all the new Keys, in order of offsets, and add any backpointers as needed, making sure to also link them
        // to whatever surviving existing Keys we might still have.
        update.getKeyUpdates().stream()
              .filter(keyUpdate -> !keyUpdate.isDeleted())
              .sorted(Comparator.comparingLong(BucketUpdate.KeyUpdate::getOffset))
              .forEach(keyUpdate -> {
                    if (previousOffset.get() != Attributes.NULL_ATTRIBUTE_VALUE) {
                        // Only add a backpointer if we have another Key ahead of it.
                        updateInstructions.withAttribute(generateBackpointerUpdate(keyUpdate.getOffset(), previousOffset.get()));
                    }

                    updateInstructions.entryAdded();
                    previousOffset.set(keyUpdate.getOffset());
                });
    }
private void generateBackpointerUpdates ( BucketUpdate update , UpdateInstructions updateInstructions ) { AtomicLong previousOffset = new AtomicLong ( Attributes . NULL_ATTRIBUTE_VALUE ) ; AtomicBoolean previousReplaced = new AtomicBoolean ( false ) ; AtomicBoolean first = new AtomicBoolean ( true ) ; update . getExistingKeys ( ) . stream ( ) . sorted ( Comparator . comparingLong ( BucketUpdate . KeyInfo :: getOffset ) ) . forEach ( keyInfo -> { boolean replaced = update . isKeyUpdated ( keyInfo . getKey ( ) ) ; if ( replaced ) { if ( ! first . get ( ) ) { updateInstructions . withAttribute ( generateBackpointerRemoval ( keyInfo . getOffset ( ) ) ) ; } updateInstructions . entryRemoved ( ) ; previousReplaced . set ( true ) ; } else { if ( previousReplaced . get ( ) ) { updateInstructions . withAttribute ( generateBackpointerUpdate ( keyInfo . getOffset ( ) , previousOffset . get ( ) ) ) ; previousReplaced . set ( false ) ; } previousOffset . set ( keyInfo . getOffset ( ) ) ; } first . set ( false ) ; } ) ; update . getKeyUpdates ( ) . stream ( ) . filter ( keyUpdate -> ! keyUpdate . isDeleted ( ) ) . sorted ( Comparator . comparingLong ( BucketUpdate . KeyUpdate :: getOffset ) ) . forEach ( keyUpdate -> { if ( previousOffset . get ( ) != Attributes . NULL_ATTRIBUTE_VALUE ) { updateInstructions . withAttribute ( generateBackpointerUpdate ( keyUpdate . getOffset ( ) , previousOffset . get ( ) ) ) ; } updateInstructions . entryAdded ( ) ; previousOffset . set ( keyUpdate . getOffset ( ) ) ; } ) ; }
Generates the necessary Backpointer updates for the given {@link BucketUpdate}.

@param update             The BucketUpdate to generate Backpointers for.
@param updateInstructions A {@link UpdateInstructions} object to collect updates into.