2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.dom.broker;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ArrayListMultimap;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.ImmutableBiMap;
14 import com.google.common.collect.ImmutableBiMap.Builder;
15 import com.google.common.collect.ImmutableMap;
16 import com.google.common.collect.Maps;
17 import com.google.common.collect.Multimap;
18 import java.util.ArrayList;
19 import java.util.Collection;
21 import java.util.Map.Entry;
23 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeShard;
26 import org.opendaylight.mdsal.dom.store.inmemory.DOMDataTreeShardProducer;
27 import org.opendaylight.mdsal.dom.store.inmemory.DOMDataTreeShardWriteTransaction;
28 import org.opendaylight.mdsal.dom.store.inmemory.WriteableDOMDataTreeShard;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 final class ProducerLayout {
35 private static final Logger LOG = LoggerFactory.getLogger(ProducerLayout.class);
37 private final BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducer;
38 private final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> children;
39 private final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap;
41 private ProducerLayout(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap,
42 final BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducer,
43 final Map<DOMDataTreeIdentifier, DOMDataTreeProducer> children) {
44 this.shardMap = ImmutableMap.copyOf(shardMap);
45 this.idToProducer = Preconditions.checkNotNull(idToProducer);
46 this.children = Preconditions.checkNotNull(children);
49 static ProducerLayout create(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
50 return new ProducerLayout(shardMap, mapIdsToProducer(shardMap), ImmutableMap.of());
53 private static BiMap<DOMDataTreeIdentifier, DOMDataTreeShardProducer> mapIdsToProducer(
54 final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
55 final Multimap<DOMDataTreeShard, DOMDataTreeIdentifier> shardToId = ArrayListMultimap.create();
56 // map which identifier belongs to which shard
57 for (final Entry<DOMDataTreeIdentifier, DOMDataTreeShard> entry : shardMap.entrySet()) {
58 shardToId.put(entry.getValue(), entry.getKey());
61 final Builder<DOMDataTreeIdentifier, DOMDataTreeShardProducer> idToProducerBuilder = ImmutableBiMap.builder();
62 for (final Entry<DOMDataTreeShard, Collection<DOMDataTreeIdentifier>> entry : shardToId.asMap().entrySet()) {
63 if (entry.getKey() instanceof WriteableDOMDataTreeShard) {
64 //create a single producer for all prefixes in a single shard
65 final DOMDataTreeShardProducer producer = ((WriteableDOMDataTreeShard) entry.getKey())
66 .createProducer(entry.getValue());
67 // id mapped to producers
68 for (final DOMDataTreeIdentifier id : entry.getValue()) {
69 idToProducerBuilder.put(id, producer);
72 LOG.error("Unable to create a producer for shard that's not a WriteableDOMDataTreeShard");
76 return idToProducerBuilder.build();
79 ProducerLayout addChild(final DOMDataTreeProducer producer, final Collection<DOMDataTreeIdentifier> subtrees) {
80 final ImmutableMap.Builder<DOMDataTreeIdentifier, DOMDataTreeProducer> cb = ImmutableMap.builder();
82 for (final DOMDataTreeIdentifier s : subtrees) {
86 return new ProducerLayout(shardMap, idToProducer, cb.build());
89 ProducerLayout reshard(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
90 return new ProducerLayout(shardMap, mapIdsToProducer(shardMap), children);
93 boolean haveSubtree(final DOMDataTreeIdentifier subtree) {
94 for (final DOMDataTreeIdentifier i : shardMap.keySet()) {
95 if (i.contains(subtree)) {
103 DOMDataTreeProducer lookupChild(final DOMDataTreeIdentifier path) {
104 for (final Entry<DOMDataTreeIdentifier, DOMDataTreeProducer> e : children.entrySet()) {
105 if (e.getKey().contains(path)) {
106 // FIXME: does this match wildcards?
114 Set<DOMDataTreeIdentifier> getChildTrees() {
115 return children.keySet();
118 void checkAvailable(final Collection<PathArgument> base, final PathArgument child) {
119 if (!children.isEmpty()) {
120 final Collection<PathArgument> args = new ArrayList<>(base.size() + 1);
124 final YangInstanceIdentifier path = YangInstanceIdentifier.create(args);
125 for (final DOMDataTreeIdentifier c : children.keySet()) {
126 Preconditions.checkArgument(!c.getRootIdentifier().contains(path),
127 "Path {%s} is not available to this cursor since it's already claimed by a child producer", path);
132 Map<DOMDataTreeIdentifier, DOMDataTreeShardWriteTransaction> createTransactions() {
133 return Maps.transformValues(idToProducer, DOMDataTreeShardProducer::createTransaction);