7a439c34fbfe3c88e4a5ace4259ab652f00fb5f4
[onosfw.git] /
1 /*
2  * Copyright 2015 Open Networking Laboratory
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onosproject.store.consistent.impl;
17
18 import org.onosproject.store.service.AsyncAtomicCounter;
19
20 import java.util.concurrent.CompletableFuture;
21 import static com.google.common.base.Preconditions.checkNotNull;
22
23 /**
24  * Default implementation for a distributed AsyncAtomicCounter backed by
25  * partitioned Raft DB.
26  * <p>
27  * The initial value will be zero.
28  */
29 public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter {
30
31     private final String name;
32     private final Database database;
33     private final MeteringAgent monitor;
34
35     private static final String PRIMITIVE_NAME = "atomicCounter";
36     private static final String INCREMENT_AND_GET = "incrementAndGet";
37     private static final String GET_AND_INCREMENT = "getAndIncrement";
38     private static final String GET_AND_ADD = "getAndAdd";
39     private static final String ADD_AND_GET = "addAndGet";
40     private static final String GET = "get";
41
42     public DefaultAsyncAtomicCounter(String name,
43                                      Database database,
44                                      boolean meteringEnabled) {
45         this.name = checkNotNull(name);
46         this.database = checkNotNull(database);
47         this.monitor = new MeteringAgent(PRIMITIVE_NAME, name, meteringEnabled);
48     }
49
50     @Override
51     public CompletableFuture<Long> incrementAndGet() {
52         final MeteringAgent.Context timer = monitor.startTimer(INCREMENT_AND_GET);
53         return addAndGet(1L)
54                 .whenComplete((r, e) -> timer.stop(e));
55     }
56
57     @Override
58     public CompletableFuture<Long> get() {
59         final MeteringAgent.Context timer = monitor.startTimer(GET);
60         return database.counterGet(name)
61                 .whenComplete((r, e) -> timer.stop(e));
62     }
63
64     @Override
65     public CompletableFuture<Long> getAndIncrement() {
66         final MeteringAgent.Context timer = monitor.startTimer(GET_AND_INCREMENT);
67         return getAndAdd(1L)
68                 .whenComplete((r, e) -> timer.stop(e));
69     }
70
71     @Override
72     public CompletableFuture<Long> getAndAdd(long delta) {
73         final MeteringAgent.Context timer = monitor.startTimer(GET_AND_ADD);
74         return database.counterGetAndAdd(name, delta)
75                        .whenComplete((r, e) -> timer.stop(e));
76     }
77
78     @Override
79     public CompletableFuture<Long> addAndGet(long delta) {
80         final MeteringAgent.Context timer = monitor.startTimer(ADD_AND_GET);
81         return database.counterAddAndGet(name, delta)
82                        .whenComplete((r, e) -> timer.stop(e));
83     }
84 }