+ @Override
+ public void captureSnapshotIfReady(final ReplicatedLogEntry replicatedLogEntry) {
+ final ConfigParams config = context.getConfigParams();
+ final long journalSize = replicatedLogEntry.getIndex() + 1;
+ final long dataThreshold = context.getTotalMemory() * config.getSnapshotDataThresholdPercentage() / 100;
+
+ if (journalSize % config.getSnapshotBatchCount() == 0 || getDataSizeForSnapshotCheck() > dataThreshold) {
+ boolean started = context.getSnapshotManager().capture(replicatedLogEntry,
+ context.getCurrentBehavior().getReplicatedToAllIndex());
+ if (started && !context.hasFollowers()) {
+ dataSizeSinceLastSnapshot = 0;
+ }
+ }
+ }
+
+ private long getDataSizeForSnapshotCheck() {
+ if (!context.hasFollowers()) {
+ // When we do not have followers we do not maintain an in-memory log
+ // due to this the journalSize will never become anything close to the
+ // snapshot batch count. In fact will mostly be 1.
+ // Similarly since the journal's dataSize depends on the entries in the
+ // journal the journal's dataSize will never reach a value close to the
+ // memory threshold.
+ // By maintaining the dataSize outside the journal we are tracking essentially
+ // what we have written to the disk however since we no longer are in
+ // need of doing a snapshot just for the sake of freeing up memory we adjust
+ // the real size of data by the DATA_SIZE_DIVIDER so that we do not snapshot as often
+ // as if we were maintaining a real snapshot
+ return dataSizeSinceLastSnapshot / DATA_SIZE_DIVIDER;
+ } else {
+ return dataSize();
+ }
+ }
+