61e8e3a939f71aba0df1c99217686e1dad1f2b6f
[controller.git] / opendaylight / md-sal / sal-dom-spi / src / main / java / org / opendaylight / controller / md / sal / dom / spi / AbstractRegistrationTree.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.md.sal.dom.spi;
9
10 import java.util.concurrent.locks.ReadWriteLock;
11 import java.util.concurrent.locks.ReentrantReadWriteLock;
12 import javax.annotation.Nonnull;
13 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
14
15 /**
16  * An abstract tree of registrations. Allows a read-only snapshot to be taken.
17  *
18  * @param <T> Type of registered object
19  *
20  * @deprecated Use {@link org.opendaylight.mdsal.dom.spi.AbstractRegistrationTree} instead.
21  */
22 @Deprecated
23 public abstract class AbstractRegistrationTree<T> {
24     private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
25     private final RegistrationTreeNode<T> rootNode = new RegistrationTreeNode<>(null, null);
26
27     protected AbstractRegistrationTree() {
28
29     }
30
31     /**
32      * Acquire the read-write lock. This should be done before invoking {@link #findNodeFor(Iterable)}.
33      */
34     protected final void takeLock() {
35         rwLock.writeLock().lock();
36     }
37
38     /**
39      * Release the read-write lock. This should be done after invocation of {@link #findNodeFor(Iterable)}
40      * and modification of the returned node. Note that callers should do so in a finally block.
41      */
42     protected final void releaseLock() {
43         rwLock.writeLock().unlock();
44     }
45
46     /**
47      * Find an existing, or allocate a fresh, node for a particular path. Must be called with the
48      * read-write lock held.
49      *
50      * @param path Path to find a node for
51      * @return A registration node for the specified path
52      */
53     @Nonnull protected final RegistrationTreeNode<T> findNodeFor(@Nonnull final Iterable<PathArgument> path) {
54         RegistrationTreeNode<T> walkNode = rootNode;
55         for (final PathArgument arg : path) {
56             walkNode = walkNode.ensureChild(arg);
57         }
58
59         return walkNode;
60     }
61
62     /**
63      * Add a registration to a particular node. The node must have been returned via {@link #findNodeFor(Iterable)}
64      * and the lock must still be held.
65      *
66      * @param node Tree node
67      * @param registration Registration instance
68      */
69     protected final void addRegistration(@Nonnull final RegistrationTreeNode<T> node, @Nonnull final T registration) {
70         node.addRegistration(registration);
71     }
72
73     /**
74      * Remove a registration from a particular node. This method must not be called while the read-write lock
75      * is held.
76      *
77      * @param node Tree node
78      * @param registration Registration instance
79      */
80     protected final void removeRegistration(@Nonnull final RegistrationTreeNode<T> node,
81             @Nonnull final T registration) {
82         // Take the write lock
83         rwLock.writeLock().lock();
84         try {
85             node.removeRegistration(registration);
86         } finally {
87             // Always release the lock
88             rwLock.writeLock().unlock();
89         }
90     }
91
92     /**
93      * Obtain a tree snapshot. This snapshot ensures a consistent view of
94      * registrations. The snapshot should be closed as soon as it is not required,
95      * because each unclosed instance blocks modification of this tree.
96      *
97      * @return A snapshot instance.
98      */
99     @Nonnull public final RegistrationTreeSnapshot<T> takeSnapshot() {
100         final RegistrationTreeSnapshot<T> ret = new RegistrationTreeSnapshot<>(rwLock.readLock(), rootNode);
101         rwLock.readLock().lock();
102         return ret;
103     }
104 }