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
9 package org.opendaylight.controller.cluster.datastore.entityownership;
11 import static org.opendaylight.controller.cluster.datastore.entityownership.EntityOwnersModel.entityTypeFromEntityPath;
13 import com.google.common.base.Strings;
14 import java.util.Collection;
15 import java.util.HashMap;
17 import java.util.Optional;
18 import javax.annotation.Nonnull;
19 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
23 import tech.pantheon.triemap.TrieMap;
26 * EntityOwnershipStatistics is a utility class that keeps track of ownership statistics for the candidates and
27 * caches it for quick count queries.
29 * While the entity ownership model does maintain the information about which entity is owned by which candidate
30 * finding out how many entities of a given type are owned by a given candidate is not an efficient query.
32 class EntityOwnershipStatistics extends AbstractEntityOwnerChangeListener {
34 private final TrieMap<String, TrieMap<String, Long>> statistics = TrieMap.create();
36 EntityOwnershipStatistics(){
40 public void onDataTreeChanged(@Nonnull final Collection<DataTreeCandidate> changes) {
41 for (DataTreeCandidate change : changes) {
42 DataTreeCandidateNode changeRoot = change.getRootNode();
43 LeafNode<?> ownerLeaf = (LeafNode<?>) changeRoot.getDataAfter().get();
44 String entityType = entityTypeFromEntityPath(change.getRootPath());
45 String newOwner = extractOwner(ownerLeaf);
46 if (!Strings.isNullOrEmpty(newOwner)) {
47 updateStatistics(entityType, newOwner, 1);
50 Optional<NormalizedNode<?, ?>> dataBefore = changeRoot.getDataBefore();
51 if (dataBefore.isPresent()) {
52 String origOwner = extractOwner((LeafNode<?>) changeRoot.getDataBefore().get());
53 if (!Strings.isNullOrEmpty(origOwner)) {
54 updateStatistics(entityType, origOwner, -1);
60 Map<String, Map<String, Long>> all() {
61 Map<String, Map<String, Long>> snapshot = new HashMap<>();
62 for (String entityType : statistics.immutableSnapshot().keySet()) {
63 snapshot.put(entityType, byEntityType(entityType));
68 Map<String, Long> byEntityType(final String entityType) {
69 if (statistics.get(entityType) != null) {
70 return statistics.get(entityType).immutableSnapshot();
72 return new HashMap<>();
75 private void updateStatistics(final String entityType, final String candidateName, final long count) {
76 TrieMap<String, Long> map = statistics.get(entityType);
78 map = TrieMap.create();
79 map.put(candidateName, count);
80 statistics.put(entityType, map);
82 map.merge(candidateName, count, (ownedEntities, addedEntities) -> ownedEntities + addedEntities);