ReadStateHelper rollback() { if(pending == null) throw new IllegalStateException(); return new ReadStateHelper(newReadState(current.getVersion(), pending.getStateEngine()), null); }
readStates.current())) { task.populate(writeState); populateStatus.success(); ReadStateHelper candidate = readStates.roundtrip(toVersion); cycleStatus.readState(candidate.pending()); candidate = checkIntegrity(listeners, candidate, artifacts); validate(listeners, candidate.pending()); announce(listeners, candidate.pending()); readStates = candidate.commit(); cycleStatus.readState(readStates.current()).success(); } catch (Throwable th) { if (artifacts.hasReverseDelta()) { applyDelta(artifacts.reverseDelta, candidate.pending().getStateEngine()); readStates = candidate.rollback();
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(); throw new ChecksumValidationException(Blob.Type.REVERSE_DELTA); result = readStates.swap();
client.triggerRefreshTo(versionDesired); if (client.getCurrentVersionId() == versionDesired) { readState = ReadStateHelper.newReadState(client.getCurrentVersionId(), client.getStateEngine()); readStates = ReadStateHelper.restored(readState); restoreAction.restore(readStates.current().getStateEngine(), newObjectMapper.getStateEngine());
/** * Run a compaction cycle, will produce a data state with exactly the same data as currently, but * reorganized so that ordinal holes are filled. This may need to be run multiple times to arrive * at an optimal state. * * @param config specifies what criteria to use to determine whether a compaction is necessary * @return the version identifier of the produced state, or AnnouncementWatcher.NO_ANNOUNCEMENT_AVAILABLE if compaction was unnecessary. */ public long runCompactionCycle(HollowCompactor.CompactionConfig config) { if (config != null && readStates.hasCurrent()) { final HollowCompactor compactor = new HollowCompactor(getWriteEngine(), readStates.current().getStateEngine(), config); if (compactor.needsCompaction()) { return runCycle(newState -> compactor.compact()); } } return NO_ANNOUNCEMENT_AVAILABLE; }
static ReadStateHelper restored(ReadState state) { return new ReadStateHelper(state, null); }
if (!readStates.hasCurrent()) { localListeners.fireNewDeltaChain(toVersion);
private HollowProducer( BlobStager blobStager, Publisher publisher, Announcer announcer, List<? extends HollowProducerEventListener> eventListeners, VersionMinter versionMinter, Executor snapshotPublishExecutor, int numStatesBetweenSnapshots, long targetMaxTypeShardSize, HollowMetricsCollector<HollowProducerMetrics> metricsCollector, BlobStorageCleaner blobStorageCleaner, SingleProducerEnforcer singleProducerEnforcer) { this.publisher = publisher; this.announcer = announcer; this.versionMinter = versionMinter; this.blobStager = blobStager; this.singleProducerEnforcer = singleProducerEnforcer; this.snapshotPublishExecutor = snapshotPublishExecutor == null ? Runnable::run : snapshotPublishExecutor; this.numStatesBetweenSnapshots = numStatesBetweenSnapshots; HollowWriteStateEngine writeEngine = new HollowWriteStateEngine(); writeEngine.setTargetMaxTypeShardSize(targetMaxTypeShardSize); this.objectMapper = new HollowObjectMapper(writeEngine); this.readStates = ReadStateHelper.newDeltaChain(); this.blobStorageCleaner = blobStorageCleaner; this.listeners = new ListenerSupport(eventListeners.stream().distinct().collect(toList())); this.metrics = new HollowProducerMetrics(); this.metricsCollector = metricsCollector; }
private void stageBlob(long toVersion, Artifacts artifacts, Blob.Type blobType) throws IOException { HollowBlobWriter writer = new HollowBlobWriter(getWriteEngine()); switch (blobType) { case SNAPSHOT: artifacts.snapshot = blobStager.openSnapshot(toVersion); artifacts.snapshot.write(writer); break; case DELTA: artifacts.delta = blobStager.openDelta(readStates.current().getVersion(), toVersion); artifacts.delta.write(writer); break; case REVERSE_DELTA: artifacts.reverseDelta = blobStager.openReverseDelta(toVersion, readStates.current().getVersion()); artifacts.reverseDelta.write(writer); break; default: throw new IllegalStateException("unknown type, type=" + blobType); } }
static ReadStateHelper newDeltaChain() { return new ReadStateHelper(null, null); }
stageBlob(toVersion, artifacts, Blob.Type.SNAPSHOT); if (readStates.hasCurrent()) { stageBlob(toVersion, artifacts, Blob.Type.DELTA); stageBlob(toVersion, artifacts, Blob.Type.REVERSE_DELTA);
ReadStateHelper roundtrip(long version) { if(pending != null) throw new IllegalStateException(); return new ReadStateHelper(this.current, newReadState(version, new HollowReadStateEngine())); }
ReadStateHelper commit() { if(pending == null) throw new IllegalStateException(); return new ReadStateHelper(this.pending, null); }
/** * Swap underlying state engines between current and pending while keeping the versions consistent; * used after delta integrity checks have altered the underlying state engines. * * @return */ ReadStateHelper swap() { return new ReadStateHelper(newReadState(current.getVersion(), pending.getStateEngine()), newReadState(pending.getVersion(), current.getStateEngine())); }