Refactor write tracking implementation 78/77478/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 4 Nov 2018 17:29:48 +0000 (18:29 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 4 Nov 2018 17:55:27 +0000 (18:55 +0100)
Rather than duplicating code which wraps a package-internal class,
provide a subclass hook in TypedWriteTransactionImpl, so that it
write-tracking defaults to no-op and is optionally wrapped.

This removes a lot of duplicated code, making the result equally
performant and more maintainable. It also removes the need to leak
TypedWriteTransactionImpl.delegate to the package and tracking
them in two fields.

Change-Id: I636818f0048090c145e6fabba198238dad1e6922
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/TransactionAdapter.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/TypedReadTransactionImpl.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/TypedReadWriteTransactionImpl.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/TypedTransaction.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/TypedWriteTransactionImpl.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/WriteTrackingTypedReadWriteTransactionImpl.java
binding/mdsal-binding-util/src/main/java/org/opendaylight/mdsal/binding/util/WriteTrackingTypedWriteTransactionImpl.java

index 2e98178d83f0cf87e83162ddc55862dbd2a1dc9a..2a856877a246099cbb318f142977a557052cc7a5 100644 (file)
@@ -62,7 +62,7 @@ public final class TransactionAdapter {
      */
     public static WriteTransaction toWriteTransaction(final TypedWriteTransaction<? extends Datastore> datastoreTx) {
         if (datastoreTx instanceof TypedWriteTransactionImpl) {
-            final TypedWriteTransactionImpl<?> txImpl = (TypedWriteTransactionImpl<?>) datastoreTx;
+            final TypedWriteTransactionImpl<?, ?> txImpl = (TypedWriteTransactionImpl<?, ?>) datastoreTx;
             return new WriteTransactionAdapter<>(txImpl.getDatastoreType(), txImpl);
         }
         throw new IllegalArgumentException("Unsupported TypedWriteTransaction implementation "
index c06e24081540423ed0f7085943b12b7fc32261c9..3176b924e1ed260ad5e50f4ff82085bdcc81b555 100644 (file)
@@ -18,22 +18,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  *
  * @param <D> The datastore which the transaction targets.
  */
-class TypedReadTransactionImpl<D extends Datastore> extends TypedTransaction<D>
+final class TypedReadTransactionImpl<D extends Datastore> extends TypedTransaction<D, ReadTransaction>
         implements TypedReadTransaction<D> {
-    private final ReadTransaction delegate;
-
-    TypedReadTransactionImpl(Class<D> datastoreType, ReadTransaction realTx) {
-        super(datastoreType);
-        this.delegate = realTx;
-    }
-
-    @Override
-    public <T extends DataObject> FluentFuture<Optional<T>> read(InstanceIdentifier<T> path) {
-        return FluentFuture.from(delegate.read(getDatastoreType(), path));
+    TypedReadTransactionImpl(final Class<D> datastoreType, final ReadTransaction realTx) {
+        super(datastoreType, realTx);
     }
 
     @Override
-    public Object getIdentifier() {
-        return delegate.getIdentifier();
+    public <T extends DataObject> FluentFuture<Optional<T>> read(final InstanceIdentifier<T> path) {
+        return delegate().read(getDatastoreType(), path);
     }
 }
index f78b4cd4fe6b53b7289da529514fe38535e39bc9..ae121603f3b5760cf0b154c87b987e18d0ef6c4f 100644 (file)
@@ -19,18 +19,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * @param <D> The datastore which the transaction targets.
  */
 class TypedReadWriteTransactionImpl<D extends Datastore>
-        extends TypedWriteTransactionImpl<D>
+        extends TypedWriteTransactionImpl<D, ReadWriteTransaction>
         implements TypedReadWriteTransaction<D> {
-    // Temporarily package protected for TransactionAdapter
-    final ReadWriteTransaction delegate;
-
-    TypedReadWriteTransactionImpl(Class<D> datastoreType, ReadWriteTransaction realTx) {
+    TypedReadWriteTransactionImpl(final Class<D> datastoreType, final ReadWriteTransaction realTx) {
         super(datastoreType, realTx);
-        this.delegate = realTx;
     }
 
     @Override
-    public <T extends DataObject> FluentFuture<Optional<T>> read(InstanceIdentifier<T> path) {
-        return FluentFuture.from(delegate.read(getDatastoreType(), path));
+    public final <T extends DataObject> FluentFuture<Optional<T>> read(final InstanceIdentifier<T> path) {
+        return delegate().read(getDatastoreType(), path);
     }
 }
index 3880805348bbb1a74678af64f29cc5c5bc502ec8..2da4724819be8c6f4ac87a06e64c1ebf1f111a11 100644 (file)
@@ -7,16 +7,25 @@
  */
 package org.opendaylight.mdsal.binding.util;
 
+import org.opendaylight.mdsal.binding.api.Transaction;
+import org.opendaylight.mdsal.binding.spi.ForwardingTransaction;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 
-abstract class TypedTransaction<D extends Datastore> {
+abstract class TypedTransaction<D extends Datastore, X extends Transaction> extends ForwardingTransaction {
     private final LogicalDatastoreType datastoreType;
+    private final X delegate;
 
-    TypedTransaction(final Class<D> datastoreType) {
+    TypedTransaction(final Class<D> datastoreType, final X delegate) {
         this.datastoreType = Datastore.toType(datastoreType);
+        this.delegate = delegate;
+    }
+
+    @Override
+    protected final X delegate() {
+        return delegate;
     }
 
     final LogicalDatastoreType getDatastoreType() {
-        return this.datastoreType;
+        return datastoreType;
     }
 }
index a72069eb3ec46497765ed5422bcc50cc7cf04a84..60fa3b98ae5155314b5ab5968c2c45ae7b93e73c 100644 (file)
@@ -15,46 +15,47 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * Implementation of {@link TypedWriteTransaction}.
  *
  * @param <D> The datastore which the transaction targets.
+ * @param <X> WriteTransaction type
  */
-class TypedWriteTransactionImpl<D extends Datastore> extends TypedTransaction<D>
+class TypedWriteTransactionImpl<D extends Datastore, X extends WriteTransaction> extends TypedTransaction<D, X>
         implements TypedWriteTransaction<D> {
-    // Temporarily package protected for TransactionAdapter
-    final WriteTransaction delegate;
-
-    TypedWriteTransactionImpl(final Class<D> datastoreType, final WriteTransaction realTx) {
-        super(datastoreType);
-        this.delegate = realTx;
+    TypedWriteTransactionImpl(final Class<D> datastoreType, final X realTx) {
+        super(datastoreType, realTx);
     }
 
     @Override
-    public <T extends DataObject> void put(final InstanceIdentifier<T> path, final T data) {
-        delegate.put(getDatastoreType(), path, data);
+    public final <T extends DataObject> void put(final InstanceIdentifier<T> path, final T data) {
+        delegate().put(getDatastoreType(), path, data);
+        postOperation();
     }
 
     @Override
-    public <T extends DataObject> void put(final InstanceIdentifier<T> path, final T data,
+    public final <T extends DataObject> void put(final InstanceIdentifier<T> path, final T data,
             final boolean createMissingParents) {
-        delegate.put(getDatastoreType(), path, data, createMissingParents);
+        delegate().put(getDatastoreType(), path, data, createMissingParents);
+        postOperation();
     }
 
     @Override
-    public <T extends DataObject> void merge(final InstanceIdentifier<T> path, final T data) {
-        delegate.merge(getDatastoreType(), path, data);
+    public final <T extends DataObject> void merge(final InstanceIdentifier<T> path, final T data) {
+        delegate().merge(getDatastoreType(), path, data);
+        postOperation();
     }
 
     @Override
-    public <T extends DataObject> void merge(final InstanceIdentifier<T> path, final T data,
+    public final <T extends DataObject> void merge(final InstanceIdentifier<T> path, final T data,
             final boolean createMissingParents) {
-        delegate.merge(getDatastoreType(), path, data, createMissingParents);
+        delegate().merge(getDatastoreType(), path, data, createMissingParents);
+        postOperation();
     }
 
     @Override
-    public void delete(final InstanceIdentifier<?> path) {
-        delegate.delete(getDatastoreType(), path);
+    public final void delete(final InstanceIdentifier<?> path) {
+        delegate().delete(getDatastoreType(), path);
+        postOperation();
     }
 
-    @Override
-    public Object getIdentifier() {
-        return delegate.getIdentifier();
+    void postOperation() {
+        // Defaults to no-op
     }
 }
index f882aabafb23dd382e7aef84612098b7cec0e7fe..2625133944ca674f8f204327057f62b7c1adfd5d 100644 (file)
@@ -8,55 +8,28 @@
 package org.opendaylight.mdsal.binding.util;
 
 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Read-write typed transaction which keeps track of writes.
  */
-class WriteTrackingTypedReadWriteTransactionImpl<D extends Datastore> extends TypedReadWriteTransactionImpl<D>
+final class WriteTrackingTypedReadWriteTransactionImpl<D extends Datastore> extends TypedReadWriteTransactionImpl<D>
         implements WriteTrackingTransaction {
 
     // This is volatile to ensure we get the latest value; transactions aren't supposed to be used in multiple threads,
     // but the cost here is tiny (one read penalty at the end of a transaction) so we play it safe
     private volatile boolean written;
 
-    WriteTrackingTypedReadWriteTransactionImpl(Class<D> datastoreType, ReadWriteTransaction realTx) {
+    WriteTrackingTypedReadWriteTransactionImpl(final Class<D> datastoreType, final ReadWriteTransaction realTx) {
         super(datastoreType, realTx);
     }
 
     @Override
-    public <T extends DataObject> void put(InstanceIdentifier<T> path, T data) {
-        super.put(path, data);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void put(InstanceIdentifier<T> path, T data, boolean createMissingParents) {
-        super.put(path, data, createMissingParents);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void merge(InstanceIdentifier<T> path, T data) {
-        super.merge(path, data);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void merge(InstanceIdentifier<T> path, T data, boolean createMissingParents) {
-        super.merge(path, data, createMissingParents);
-        written = true;
+    public boolean isWritten() {
+        return written;
     }
 
     @Override
-    public void delete(InstanceIdentifier<?> path) {
-        super.delete(path);
+    void postOperation() {
         written = true;
     }
-
-    @Override
-    public boolean isWritten() {
-        return written;
-    }
 }
index b6c322340da876509707bd7be780ee7f92de9099..d1ce3fee777eaa42a00339fcfbc6165ab52f44a3 100644 (file)
@@ -8,55 +8,28 @@
 package org.opendaylight.mdsal.binding.util;
 
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Write typed transaction which keeps track of writes.
  */
-class WriteTrackingTypedWriteTransactionImpl<D extends Datastore> extends TypedWriteTransactionImpl<D>
-        implements WriteTrackingTransaction {
+final class WriteTrackingTypedWriteTransactionImpl<D extends Datastore>
+        extends TypedWriteTransactionImpl<D, WriteTransaction> implements WriteTrackingTransaction {
 
     // This is volatile to ensure we get the latest value; transactions aren't supposed to be used in multiple threads,
     // but the cost here is tiny (one read penalty at the end of a transaction) so we play it safe
     private volatile boolean written;
 
-    WriteTrackingTypedWriteTransactionImpl(Class<D> datastoreType, WriteTransaction realTx) {
+    WriteTrackingTypedWriteTransactionImpl(final Class<D> datastoreType, final WriteTransaction realTx) {
         super(datastoreType, realTx);
     }
 
     @Override
-    public <T extends DataObject> void put(InstanceIdentifier<T> path, T data) {
-        super.put(path, data);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void put(InstanceIdentifier<T> path, T data, boolean createMissingParents) {
-        super.put(path, data, createMissingParents);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void merge(InstanceIdentifier<T> path, T data) {
-        super.merge(path, data);
-        written = true;
-    }
-
-    @Override
-    public <T extends DataObject> void merge(InstanceIdentifier<T> path, T data, boolean createMissingParents) {
-        super.merge(path, data, createMissingParents);
-        written = true;
+    public boolean isWritten() {
+        return written;
     }
 
     @Override
-    public void delete(InstanceIdentifier<?> path) {
-        super.delete(path);
+    void postOperation() {
         written = true;
     }
-
-    @Override
-    public boolean isWritten() {
-        return written;
-    }
 }