X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-inmemory-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fsal%2Fdom%2Fstore%2Fimpl%2FDOMStoreTransactionChainImpl.java;h=e357c8dc9c12d52bb433487bea81a5f57a44f33e;hp=3f731cf18b66bb9305cc1ef40b867f4904343f04;hb=978152c5de3bf78ab6da5da4c2db391eec063429;hpb=0f3ae2f9e4151a60245a2b295cc7998f0d0e745f diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMStoreTransactionChainImpl.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMStoreTransactionChainImpl.java index 3f731cf18b..e357c8dc9c 100644 --- a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMStoreTransactionChainImpl.java +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMStoreTransactionChainImpl.java @@ -8,217 +8,44 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import com.google.common.base.Preconditions; -import java.util.AbstractMap.SimpleEntry; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import org.opendaylight.controller.md.sal.dom.store.impl.SnapshotBackedWriteTransaction.TransactionReadyPrototype; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; +import org.opendaylight.controller.sal.core.spi.data.AbstractSnapshotBackedTransactionChain; import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction; +import org.opendaylight.controller.sal.core.spi.data.SnapshotBackedWriteTransaction; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -final class DOMStoreTransactionChainImpl extends TransactionReadyPrototype implements DOMStoreTransactionChain { - private static abstract class State { - /** - * Allocate a new snapshot. - * - * @return A new snapshot - */ - protected abstract DataTreeSnapshot getSnapshot(); - } - - private static final class Idle extends State { - private final InMemoryDOMDataStore store; - - Idle(final InMemoryDOMDataStore store) { - this.store = Preconditions.checkNotNull(store); - } - - @Override - protected DataTreeSnapshot getSnapshot() { - return store.takeSnapshot(); - } - } - - /** - * We have a transaction out there. - */ - private static final class Allocated extends State { - private static final AtomicReferenceFieldUpdater SNAPSHOT_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(Allocated.class, DataTreeSnapshot.class, "snapshot"); - private final DOMStoreWriteTransaction transaction; - private volatile DataTreeSnapshot snapshot; - - Allocated(final DOMStoreWriteTransaction transaction) { - this.transaction = Preconditions.checkNotNull(transaction); - } - - public DOMStoreWriteTransaction getTransaction() { - return transaction; - } - - @Override - protected DataTreeSnapshot getSnapshot() { - final DataTreeSnapshot ret = snapshot; - Preconditions.checkState(ret != null, "Previous transaction %s is not ready yet", transaction.getIdentifier()); - return ret; - } - - void setSnapshot(final DataTreeSnapshot snapshot) { - final boolean success = SNAPSHOT_UPDATER.compareAndSet(this, null, snapshot); - Preconditions.checkState(success, "Transaction %s has already been marked as ready", transaction.getIdentifier()); - } - } - - /** - * Chain is logically shut down, no further allocation allowed. - */ - private static final class Shutdown extends State { - private final String message; - - Shutdown(final String message) { - this.message = Preconditions.checkNotNull(message); - } - - @Override - protected DataTreeSnapshot getSnapshot() { - throw new IllegalStateException(message); - } - } - - private static final AtomicReferenceFieldUpdater STATE_UPDATER = - AtomicReferenceFieldUpdater.newUpdater(DOMStoreTransactionChainImpl.class, State.class, "state"); - private static final Logger LOG = LoggerFactory.getLogger(DOMStoreTransactionChainImpl.class); - private static final Shutdown CLOSED = new Shutdown("Transaction chain is closed"); - private static final Shutdown FAILED = new Shutdown("Transaction chain has failed"); +final class DOMStoreTransactionChainImpl extends AbstractSnapshotBackedTransactionChain { private final InMemoryDOMDataStore store; - private final Idle idleState; - private volatile State state; DOMStoreTransactionChainImpl(final InMemoryDOMDataStore store) { this.store = Preconditions.checkNotNull(store); - idleState = new Idle(store); - state = idleState; - } - - private Entry getSnapshot() { - final State localState = state; - return new SimpleEntry<>(localState, localState.getSnapshot()); - } - - private boolean recordTransaction(final State expected, final DOMStoreWriteTransaction transaction) { - final State state = new Allocated(transaction); - return STATE_UPDATER.compareAndSet(this, expected, state); } @Override - public DOMStoreReadTransaction newReadOnlyTransaction() { - final Entry entry = getSnapshot(); - return new SnapshotBackedReadTransaction(store.nextIdentifier(), store.getDebugTransactions(), entry.getValue()); - } - - @Override - public DOMStoreReadWriteTransaction newReadWriteTransaction() { - Entry entry; - DOMStoreReadWriteTransaction ret; - - do { - entry = getSnapshot(); - ret = new SnapshotBackedReadWriteTransaction(store.nextIdentifier(), - store.getDebugTransactions(), entry.getValue(), this); - } while (!recordTransaction(entry.getKey(), ret)); - - return ret; - } - - @Override - public DOMStoreWriteTransaction newWriteOnlyTransaction() { - Entry entry; - DOMStoreWriteTransaction ret; - - do { - entry = getSnapshot(); - ret = new SnapshotBackedWriteTransaction(store.nextIdentifier(), - store.getDebugTransactions(), entry.getValue(), this); - } while (!recordTransaction(entry.getKey(), ret)); - - return ret; + protected DOMStoreThreePhaseCommitCohort createCohort(final SnapshotBackedWriteTransaction tx, final DataTreeModification tree) { + return new ChainedTransactionCommitImpl(tx, store.transactionReady(tx, tree), this); } @Override - protected void transactionAborted(final SnapshotBackedWriteTransaction tx) { - final State localState = state; - if (localState instanceof Allocated) { - final Allocated allocated = (Allocated)localState; - if (allocated.getTransaction().equals(tx)) { - final boolean success = STATE_UPDATER.compareAndSet(this, localState, idleState); - if (!success) { - LOG.info("State already transitioned from {} to {}", localState, state); - } - } - } + protected DataTreeSnapshot takeSnapshot() { + return store.takeSnapshot(); } @Override - protected DOMStoreThreePhaseCommitCohort transactionReady(final SnapshotBackedWriteTransaction tx, final DataTreeModification tree) { - final State localState = state; - - if (localState instanceof Allocated) { - final Allocated allocated = (Allocated)localState; - final DOMStoreWriteTransaction transaction = allocated.getTransaction(); - Preconditions.checkState(tx.equals(transaction), "Mis-ordered ready transaction %s last allocated was %s", tx, transaction); - allocated.setSnapshot(tree); - } else { - LOG.debug("Ignoring transaction {} readiness due to state {}", tx, localState); - } - - return new ChainedTransactionCommitImpl(tx, store.transactionReady(tx, tree), this); + protected String nextTransactionIdentifier() { + return store.nextIdentifier(); } @Override - public void close() { - final State localState = state; - - do { - Preconditions.checkState(!CLOSED.equals(localState), "Transaction chain {} has been closed", this); - - if (FAILED.equals(localState)) { - LOG.debug("Ignoring user close in failed state"); - return; - } - } while (!STATE_UPDATER.compareAndSet(this, localState, CLOSED)); + protected boolean getDebugTransactions() { + return store.getDebugTransactions(); } - void onTransactionFailed(final SnapshotBackedWriteTransaction transaction, final Throwable t) { - LOG.debug("Transaction chain {} failed on transaction {}", this, transaction, t); - state = FAILED; + void transactionFailed(final SnapshotBackedWriteTransaction transaction, final Throwable cause) { + super.onTransactionFailed(transaction, cause); } - void onTransactionCommited(final SnapshotBackedWriteTransaction transaction) { - // If the committed transaction was the one we allocated last, - // we clear it and the ready snapshot, so the next transaction - // allocated refers to the data tree directly. - final State localState = state; - - if (!(localState instanceof Allocated)) { - LOG.debug("Ignoring successful transaction {} in state {}", transaction, localState); - return; - } - - final Allocated allocated = (Allocated)localState; - final DOMStoreWriteTransaction tx = allocated.getTransaction(); - if (!tx.equals(transaction)) { - LOG.debug("Ignoring non-latest successful transaction {} in state {}", transaction, allocated); - return; - } - - if (!STATE_UPDATER.compareAndSet(this, localState, idleState)) { - LOG.debug("Transaction chain {} has already transitioned from {} to {}, not making it idle", this, localState, state); - } + void transactionCommited(final SnapshotBackedWriteTransaction transaction) { + super.onTransactionCommited(transaction); } -} \ No newline at end of file +}