Switch to using StampedLock
[mdsal.git] / dom / mdsal-dom-spi / src / main / java / org / opendaylight / mdsal / dom / spi / DOMDataTreePrefixTable.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.mdsal.dom.spi;
9
10 import com.google.common.annotations.Beta;
11 import java.util.EnumMap;
12 import java.util.Map;
13 import javax.annotation.Nonnull;
14 import javax.annotation.Nullable;
15 import javax.annotation.concurrent.NotThreadSafe;
16 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
17 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 /**
22  * Prefix table indexed by {@link DOMDataTreeIdentifier}.
23  *
24  * Stores values in tree and provides lookup of closest ancestor
25  *
26  *
27  * @param <V> Value type
28  */
29 @Beta
30 @NotThreadSafe
31 public final class DOMDataTreePrefixTable<V> {
32
33     private static final Logger LOG = LoggerFactory.getLogger(DOMDataTreePrefixTable.class);
34     private final Map<LogicalDatastoreType, DOMDataTreePrefixTableEntry<V>> roots = new EnumMap<>(LogicalDatastoreType.class);
35
36     private DOMDataTreePrefixTable() {
37
38     }
39
40     public static <V> DOMDataTreePrefixTable<V> create() {
41         return new DOMDataTreePrefixTable<>();
42     }
43
44     /**
45      *
46      * Lookups entry by provided {@link DOMDataTreeIdentifier}, if entry is not present returns
47      * closest non-null entry towards root or null if no entry towards root exists.
48      *
49      * @param prefix Prefix for lookup
50      * @return closest non-null entry towards root or null if no entry towards root exists.
51      */
52     public @Nullable DOMDataTreePrefixTableEntry<V> lookup(@Nonnull final DOMDataTreeIdentifier prefix) {
53         final DOMDataTreePrefixTableEntry<V> t = roots.get(prefix.getDatastoreType());
54         if (t == null) {
55             return null;
56         }
57
58         return t.lookup(prefix.getRootIdentifier());
59     }
60
61     /**
62      * Stores value associated to the prefix
63      *
64      * @param prefix DOM prefix of value
65      * @param value Value to be stored
66      * @throws IllegalStateException If value is already stored for provided prefix
67      */
68     public void store(@Nonnull final DOMDataTreeIdentifier prefix, @Nonnull final V value) {
69         DOMDataTreePrefixTableEntry<V> t = roots.get(prefix.getDatastoreType());
70         if (t == null) {
71             t = new DOMDataTreePrefixTableEntry<V>();
72             roots.put(prefix.getDatastoreType(), t);
73         }
74
75         t.store(prefix.getRootIdentifier(), value);
76     }
77
78     /**
79      * Removes value associated to the prefix.
80      *
81      * Value is removed only and only if full prefix match for stored value. Removal of prefix does
82      * not remove child prefixes.
83      *
84      * @param prefix
85      */
86     public void remove(@Nonnull final DOMDataTreeIdentifier prefix) {
87         final DOMDataTreePrefixTableEntry<V> t = roots.get(prefix.getDatastoreType());
88         if (t == null) {
89             LOG.warn("Shard registration {} points to non-existent table", t);
90             return;
91         }
92
93         t.remove(prefix.getRootIdentifier());
94     }
95
96 }