From 74425faef2cc216605188e70e2d2916398d85301 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 16 Sep 2016 21:17:07 +0200 Subject: [PATCH 1/1] Optimize InMemoryDOMDataTreeShardProducer All state transitions in this class are based on lock-free algorithms -- compare-and-swap and retries on conflict. Eliminate unneeded synchronized keywords, plus inline simple single-use methods. Change-Id: I87e22333bb6c3c4db324c5918481fe79d5da2592 Signed-off-by: Robert Varga (cherry picked from commit 7d465def070bd22e0ad3836119449b3063074e13) --- .../InMemoryDOMDataTreeShardProducer.java | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShardProducer.java b/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShardProducer.java index dcd867bf3c..348c46df33 100644 --- a/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShardProducer.java +++ b/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShardProducer.java @@ -10,9 +10,7 @@ package org.opendaylight.mdsal.dom.store.inmemory; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; -import java.util.AbstractMap.SimpleEntry; import java.util.Collection; -import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; @@ -40,7 +38,7 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { } @Override - protected DataTreeSnapshot getSnapshot(Object transactionId) { + protected DataTreeSnapshot getSnapshot(final Object transactionId) { return producer.takeSnapshot(); } } @@ -58,12 +56,12 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { this.transaction = Preconditions.checkNotNull(transaction); } - public InmemoryDOMDataTreeShardWriteTransaction getTransaction() { + InmemoryDOMDataTreeShardWriteTransaction getTransaction() { return transaction; } @Override - protected DataTreeSnapshot getSnapshot(Object transactionId) { + protected DataTreeSnapshot getSnapshot(final Object transactionId) { final DataTreeSnapshot ret = snapshot; Preconditions.checkState(ret != null, "Could not get snapshot for transaction %s - previous transaction %s is not ready yet", @@ -89,7 +87,7 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { } @Override - protected DataTreeSnapshot getSnapshot(Object transactionId) { + protected DataTreeSnapshot getSnapshot(final Object transactionId) { throw new IllegalStateException(message); } } @@ -99,10 +97,10 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { private final InMemoryDOMDataTreeShard parentShard; private final Collection prefixes; + private final Idle idleState = new Idle(this); private static final AtomicReferenceFieldUpdater STATE_UPDATER = AtomicReferenceFieldUpdater.newUpdater(InMemoryDOMDataTreeShardProducer.class, State.class, "state"); - private final Idle idleState = new Idle(this); private volatile State state; InMemoryDOMDataTreeShardProducer(final InMemoryDOMDataTreeShard parentShard, @@ -113,21 +111,20 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { } @Override - public synchronized InmemoryDOMDataTreeShardWriteTransaction createTransaction() { - Entry entry; - InmemoryDOMDataTreeShardWriteTransaction ret; - String transactionId = nextIdentifier(); + public InmemoryDOMDataTreeShardWriteTransaction createTransaction() { + final String transactionId = nextIdentifier(); + State localState; + InmemoryDOMDataTreeShardWriteTransaction ret; do { - entry = getSnapshot(transactionId); - ret = parentShard.createTransaction(transactionId, this, prefixes, entry.getValue()); - } while (!recordTransaction(entry.getKey(), ret)); + localState = state; + ret = parentShard.createTransaction(transactionId, this, prefixes, localState.getSnapshot(transactionId)); + } while (!STATE_UPDATER.compareAndSet(this, localState, new Allocated(ret))); return ret; } - synchronized void transactionReady(final InmemoryDOMDataTreeShardWriteTransaction tx, - final DataTreeModification modification) { + void transactionReady(final InmemoryDOMDataTreeShardWriteTransaction tx, final DataTreeModification modification) { final State localState = state; LOG.debug("Transaction was readied {}, current state {}", tx.getIdentifier(), localState); @@ -147,7 +144,7 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { * * @param transaction Transaction which completed successfully. */ - synchronized void onTransactionCommited(final InmemoryDOMDataTreeShardWriteTransaction transaction) { + void onTransactionCommited(final InmemoryDOMDataTreeShardWriteTransaction 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. @@ -174,7 +171,7 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { } } - synchronized void transactionAborted(final InmemoryDOMDataTreeShardWriteTransaction tx) { + void transactionAborted(final InmemoryDOMDataTreeShardWriteTransaction tx) { final State localState = state; if (localState instanceof Allocated) { final Allocated allocated = (Allocated)localState; @@ -188,21 +185,8 @@ class InMemoryDOMDataTreeShardProducer implements DOMDataTreeShardProducer { } } - - private Entry getSnapshot(String transactionId) { - final State localState = state; - return new SimpleEntry<>(localState, localState.getSnapshot(transactionId)); - } - - private boolean recordTransaction(final State expected, - final InmemoryDOMDataTreeShardWriteTransaction transaction) { - final State state = new Allocated(transaction); - return STATE_UPDATER.compareAndSet(this, expected, state); - } - - private String nextIdentifier() { + private static String nextIdentifier() { return "INMEMORY-SHARD-TX-" + COUNTER.getAndIncrement(); - } DataTreeSnapshot takeSnapshot() { -- 2.36.6