/** * Determine if committing this transaction will require appending a new log entry to the Raft log. * * @return true if this is not a read-only transaction and has either a config change or a key/value store mutation */ boolean addsLogEntry() { assert Thread.holdsLock(this.raft); if (this.readOnly) return false; if (this.configChange != null) return true; synchronized (this.view) { return !this.view.getWrites().isEmpty(); } }
/** * Create an instance from a local transaction and an existing temporary file. * * @param tx local transaction * @param tempFile temporary file containing serialized mutations */ NewLogEntry(final RaftKVTransaction tx, final File tempFile) throws IOException { this(new LogEntry.Data(tx.view.getWrites(), tx.getConfigChange()), tempFile); }
/** * Create an instance from a local transaction. A corresponding temporary file will be created automatically. * * @param tx local transaction */ NewLogEntry(final RaftKVTransaction tx) throws IOException { this(tx.raft, new LogEntry.Data(tx.view.getWrites(), tx.getConfigChange())); }
assert compactingMods.getKVStore() == this.kvstore; synchronized (compactingMods) { if (!compactingMods.getWrites().isEmpty()) compactingWrites = compactingMods.getWrites().immutableSnapshot(); if (!this.mods.getWrites().isEmpty()) this.modsWritesSnapshot = this.mods.getWrites().immutableSnapshot();
writesToCompact = this.mods.getWrites(); this.modsFileSyncPoint = newModsFileSyncPoint; this.kvstore = new ArrayKVStore(this.indx, this.keys, this.vals); this.mods = new MutableView(this.kvstore, null, this.mods.getWrites()); this.modsWritesSnapshot = null; if (additionalModsLength == 0) final Writes writesDuringCompaction = this.mods.getWrites(); this.mods = new MutableView(this.kvstore, null, writesToCompact); this.modsWritesSnapshot = null;
@Override public void commit() { // Grab transaction reads & writes, set to immutable final Writes writes; synchronized (this.view) { writes = this.view.getWrites(); this.view.setReadOnly(); this.cachingKV.close(); // this tells background read-ahead threads to ignore subsequent exceptions } // Apply writes and commit tx try { this.applyWritesBeforeCommitIfNotReadOnly(writes); this.inner.commit(); } finally { this.close(); } }
/** * {@inheritDoc} * * <p> * Mutable snapshots are supported by {@link RaftKVTransaction}. * * @return {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} * @throws StaleTransactionException {@inheritDoc} * @throws io.permazen.kv.RetryTransactionException {@inheritDoc} */ @Override public CloseableKVStore mutableSnapshot() { final Writes writes; synchronized (this.view) { writes = this.view.getWrites().clone(); } synchronized (this.raft) { this.verifyExecuting(); assert this.snapshotRefs != null; this.snapshotRefs.ref(); final MutableView snapshotView = new MutableView(this.snapshotRefs.getKVStore(), null, writes); return new CloseableForwardingKVStore(snapshotView, this.snapshotRefs.getUnrefCloseable()); } }
final Writes writes = tx.view.getWrites(); // synchronization not req'd here because tx is COMMIT_READY final File file = new File(this.raft.logDir, String.format("%s%019d%s", RaftKVDatabase.TX_FILE_PREFIX, tx.txId, RaftKVDatabase.TEMP_FILE_SUFFIX));
final String conflictMsg = this.checkHighPriorityConflict(tx.view.getWrites(), this.raft.dumpConflicts ? "local tx " + tx : null); if (conflictMsg != null)