Move queue/meter/flow listeners into their trackers
[controller.git] / opendaylight / md-sal / statistics-manager / src / main / java / org / opendaylight / controller / md / statistics / manager / AbstractStatsTracker.java
1 /*
2  * Copyright IBM Corporation, 2013.  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.statistics.manager;
9
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.concurrent.Future;
16
17 import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
18 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
25 import org.opendaylight.yangtools.yang.common.RpcResult;
26
27 import com.google.common.base.Function;
28 import com.google.common.base.Preconditions;
29 import com.google.common.util.concurrent.Futures;
30 import com.google.common.util.concurrent.JdkFutureAdapters;
31
32 abstract class AbstractStatsTracker<I, K> {
33     private static final Function<RpcResult<? extends TransactionAware>, TransactionId> FUNCTION =
34             new Function<RpcResult<? extends TransactionAware>, TransactionId>() {
35         @Override
36         public TransactionId apply(RpcResult<? extends TransactionAware> input) {
37             return input.getResult().getTransactionId();
38         }
39     };
40
41     private final Map<K, Long> trackedItems = new HashMap<>();
42     private final FlowCapableContext context;
43     private final long lifetimeNanos;
44
45     protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) {
46         this.context = Preconditions.checkNotNull(context);
47         this.lifetimeNanos = lifetimeNanos;
48     }
49
50     protected final InstanceIdentifierBuilder<Node> getNodeIdentifierBuilder() {
51         return InstanceIdentifier.builder(getNodeIdentifier());
52     }
53
54     protected final NodeRef getNodeRef() {
55         return context.getNodeRef();
56     }
57
58     protected final InstanceIdentifier<Node> getNodeIdentifier() {
59         return context.getNodeIdentifier();
60     }
61
62     protected final <T extends TransactionAware> void requestHelper(Future<RpcResult<T>> future, StatsRequestType type) {
63         context.registerTransaction(Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION), type);
64     }
65
66     protected final DataModificationTransaction startTransaction() {
67         return context.startDataModification();
68     }
69
70     protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
71     protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
72
73     public final synchronized void updateStats(List<I> list) {
74         final Long expiryTime = System.nanoTime() + lifetimeNanos;
75         final DataModificationTransaction trans = startTransaction();
76
77         for (final I item : list) {
78             trackedItems.put(updateSingleStat(trans, item), expiryTime);
79         }
80
81         trans.commit();
82     }
83
84     public final synchronized void cleanup(final DataModificationTransaction trans, long now) {
85         for (Iterator<Entry<K, Long>> it = trackedItems.entrySet().iterator();it.hasNext();){
86             Entry<K, Long> e = it.next();
87             if (now > e.getValue()) {
88                 cleanupSingleStat(trans, e.getKey());
89                 it.remove();
90             }
91         }
92     }
93 }