SplittingPaxosStateLog implements PaxosStateLog<V> { public static <V extends Persistable & Versionable> PaxosStateLog<V> create(SplittingParameters<V> parameters) { Preconditions.checkState(parameters.cutoffInclusive() == PaxosAcceptor.NO_LOG_ENTRY || parameters.currentLog().getGreatestLogEntry() >= parameters.cutoffInclusive(), "Cutoff value must either be -1, or the current log must contain an entry after the cutoff."); return new SplittingPaxosStateLog<>( parameters.legacyLog(), parameters.currentLog(), parameters.legacyOperationMarkers().markLegacyWrite(), parameters.legacyOperationMarkers().markLegacyRead(), parameters.cutoffInclusive(), new AtomicLong(parameters.legacyLog().getLeastLogEntry())); } private  SplittingPaxosStateLog(PaxosStateLog<V> legacyLog,
            PaxosStateLog<V> currentLog,
            Runnable markLegacyWrite,
            Runnable markLegacyRead,
            long cutoffInclusive,
            AtomicLong legacyLogLeastLogEntry); static PaxosStateLog<V> create(SplittingParameters<V> parameters); static PaxosStateLog<V> createWithMigration(
            PaxosStorageParameters params,
            Persistable.Hydrator<V> hydrator,
            LegacyOperationMarkers legacyOperationMarkers,
            OptionalLong migrateFrom); @Override void writeRound(long seq, V round); @Override byte[] readRound(long seq); @Override long getLeastLogEntry(); @Override long getGreatestLogEntry(); @Override void truncate(long toDeleteInclusive);  }
@Test public void currentLogCanBeEmptyIffCutoffIsNoLogEntryValue() { assertThatCode(() -> SplittingPaxosStateLog.create(parametersWithCutoff(PaxosAcceptor.NO_LOG_ENTRY))) .doesNotThrowAnyException(); assertThatThrownBy(() -> SplittingPaxosStateLog.create(parametersWithCutoff(7L))) .isInstanceOf(SafeIllegalStateException.class); }