hollow/src/main/java/com/netflix/hollow/api/producer/AbstractHollowProducer.java
private ReadStateHelper checkIntegrity(
            ListenerSupport.Listeners listeners, ReadStateHelper readStates, Artifacts artifacts) throws Exception {
        Status.StageWithStateBuilder status = listeners.fireIntegrityCheckStart(readStates.pending());
        try {
            ReadStateHelper result = readStates;
            HollowReadStateEngine pending = readStates.pending().getStateEngine();
            readSnapshot(artifacts.snapshot, pending);

            if (readStates.hasCurrent()) {
                HollowReadStateEngine current = readStates.current().getStateEngine();

                log.info("CHECKSUMS");
                HollowChecksum currentChecksum = HollowChecksum.forStateEngineWithCommonSchemas(current, pending);
                log.info("  CUR        " + currentChecksum);

                HollowChecksum pendingChecksum = HollowChecksum.forStateEngineWithCommonSchemas(pending, current);
                log.info("         PND " + pendingChecksum);

                if (artifacts.hasDelta()) {
                    if (!artifacts.hasReverseDelta()) {
                        throw new IllegalStateException("Both a delta and reverse delta are required");
                    }

                    // FIXME: timt: future cycles will fail unless both deltas validate
                    applyDelta(artifacts.delta, current);
                    HollowChecksum forwardChecksum = HollowChecksum.forStateEngineWithCommonSchemas(current, pending);
                    //out.format("  CUR => PND %s\n", forwardChecksum);
                    if (!forwardChecksum.equals(pendingChecksum)) {
                        throw new HollowProducer.ChecksumValidationException(HollowProducer.Blob.Type.DELTA);
                    }

                    applyDelta(artifacts.reverseDelta, pending);
                    HollowChecksum reverseChecksum = HollowChecksum.forStateEngineWithCommonSchemas(pending, current);
                    //out.format("  CUR <= PND %s\n", reverseChecksum);
                    if (!reverseChecksum.equals(currentChecksum)) {
                        throw new HollowProducer.ChecksumValidationException(HollowProducer.Blob.Type.REVERSE_DELTA);
                    }
                    result = readStates.swap();
                }
            }
            status.success();
            return result;
        } catch (Throwable th) {
            status.fail(th);
            throw th;
        } finally {
            listeners.fireIntegrityCheckComplete(status);
        }
    }
private ReadStateHelper checkIntegrity(
            ListenerSupport.Listeners listeners, ReadStateHelper readStates, Artifacts artifacts) throws Exception {
        Status.StageWithStateBuilder status = listeners.fireIntegrityCheckStart(readStates.pending());
        try {
            ReadStateHelper result = readStates;
            HollowReadStateEngine pending = readStates.pending().getStateEngine();
            readSnapshot(artifacts.snapshot, pending);

            if (readStates.hasCurrent()) {
                HollowReadStateEngine current = readStates.current().getStateEngine();

                log.info("CHECKSUMS");
                HollowChecksum currentChecksum = HollowChecksum.forStateEngineWithCommonSchemas(current, pending);
                log.info("  CUR        " + currentChecksum);

                HollowChecksum pendingChecksum = HollowChecksum.forStateEngineWithCommonSchemas(pending, current);
                log.info("         PND " + pendingChecksum);

                if (artifacts.hasDelta()) {
                    if (!artifacts.hasReverseDelta()) {
                        throw new IllegalStateException("Both a delta and reverse delta are required");
                    }

                    // FIXME: timt: future cycles will fail unless both deltas validate
                    applyDelta(artifacts.delta, current);
                    HollowChecksum forwardChecksum = HollowChecksum.forStateEngineWithCommonSchemas(current, pending);
                    //out.format("  CUR => PND %s\n", forwardChecksum);
                    if (!forwardChecksum.equals(pendingChecksum)) {
                        throw new HollowProducer.ChecksumValidationException(HollowProducer.Blob.Type.DELTA);
                    }

                    applyDelta(artifacts.reverseDelta, pending);
                    HollowChecksum reverseChecksum = HollowChecksum.forStateEngineWithCommonSchemas(pending, current);
                    //out.format("  CUR <= PND %s\n", reverseChecksum);
                    if (!reverseChecksum.equals(currentChecksum)) {
                        throw new HollowProducer.ChecksumValidationException(HollowProducer.Blob.Type.REVERSE_DELTA);
                    }
                    result = readStates.swap();
                }
            }
            status.success();
            return result;
        } catch (Throwable th) {
            status.fail(th);
            throw th;
        } finally {
            listeners.fireIntegrityCheckComplete(status);
        }
    }
private ReadStateHelper checkIntegrity ( ListenerSupport . Listeners listeners , ReadStateHelper readStates , Artifacts artifacts ) throws Exception { Status . StageWithStateBuilder status = listeners . fireIntegrityCheckStart ( readStates . pending ( ) ) ; try { ReadStateHelper result = readStates ; HollowReadStateEngine pending = readStates . pending ( ) . getStateEngine ( ) ; readSnapshot ( artifacts . snapshot , pending ) ; if ( readStates . hasCurrent ( ) ) { HollowReadStateEngine current = readStates . current ( ) . getStateEngine ( ) ; log . info ( "CHECKSUMS" ) ; HollowChecksum currentChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( current , pending ) ; log . info ( "  CUR        " + currentChecksum ) ; HollowChecksum pendingChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( pending , current ) ; log . info ( "         PND " + pendingChecksum ) ; if ( artifacts . hasDelta ( ) ) { if ( ! artifacts . hasReverseDelta ( ) ) { throw new IllegalStateException ( "Both a delta and reverse delta are required" ) ; } // FIXME: timt: future cycles will fail unless both deltas validate applyDelta ( artifacts . delta , current ) ; HollowChecksum forwardChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( current , pending ) ; //out.format("  CUR => PND %s\n", forwardChecksum); if ( ! forwardChecksum . equals ( pendingChecksum ) ) { throw new HollowProducer . ChecksumValidationException ( HollowProducer . Blob . Type . DELTA ) ; } applyDelta ( artifacts . reverseDelta , pending ) ; HollowChecksum reverseChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( pending , current ) ; //out.format("  CUR <= PND %s\n", reverseChecksum); if ( ! reverseChecksum . equals ( currentChecksum ) ) { throw new HollowProducer . ChecksumValidationException ( HollowProducer . Blob . Type . REVERSE_DELTA ) ; } result = readStates . swap ( ) ; } } status . success ( ) ; return result ; } catch ( Throwable th ) { status . fail ( th ) ; throw th ; } finally { listeners . fireIntegrityCheckComplete ( status ) ; } }
Given these read states
<p>
* S(cur) at the currently announced version
* S(pnd) at the pending version
<p>
Ensure that:
<p>
S(cur).apply(forwardDelta).checksum == S(pnd).checksum
S(pnd).apply(reverseDelta).checksum == S(cur).checksum

@return updated read states
Given these read states <p > * S ( cur ) at the currently announced version * S ( pnd ) at the pending version <p > Ensure that : <p > S ( cur ) . apply ( forwardDelta ) . checksum == S ( pnd ) . checksum S ( pnd ) . apply ( reverseDelta ) . checksum == S ( cur ) . checksum