Added tests to programming-api.
[bgpcep.git] / programming / api / src / main / java / org / opendaylight / bgpcep / programming / NanotimeUtil.java
1 /*
2  * Copyright (c) 2013 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.bgpcep.programming;
9
10 import java.math.BigInteger;
11
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.Nanotime;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 /**
17  * Util methods for {@link Nanotime}.
18  */
19 public final class NanotimeUtil {
20         private static final Logger LOG = LoggerFactory.getLogger(NanotimeUtil.class);
21         private static final BigInteger MILLION = BigInteger.valueOf(1000000);
22         private static volatile BigInteger nanoTimeOffset = null;
23
24         private NanotimeUtil() {
25         }
26
27         /**
28          * Returns current time in nanoseconds.
29          * 
30          * @return Nanotime object filled with current time in nanoseconds.
31          */
32         public static Nanotime currentTime() {
33                 return new Nanotime(BigInteger.valueOf(System.currentTimeMillis()).multiply(MILLION));
34         }
35
36         /**
37          * Returns calibrated current JVM nano time.
38          * 
39          * @return Nanotime object filled with current JVM nano time.
40          */
41         public static Nanotime currentNanoTime() {
42                 if (nanoTimeOffset == null) {
43                         calibrate();
44                 }
45                 return new Nanotime(BigInteger.valueOf(System.nanoTime()).add(nanoTimeOffset));
46         }
47
48         /**
49          * Calibrates the offset between the real-time clock providing System.currentTimeMillis() and the monotonic clock
50          * providing System.nanoTime(). This method should be called whenever there is a hint of the two diverging: either
51          * when time shifts or periodically.
52          */
53         public static void calibrate() {
54                 final long tm1 = System.currentTimeMillis();
55                 final long nt1 = System.nanoTime();
56                 final long tm2 = System.currentTimeMillis();
57                 final long nt2 = System.nanoTime();
58
59                 LOG.debug("Calibrated currentTime and nanoTime to {}m <= {}n <= {}m <= {}n", tm1, nt1, tm2, nt2);
60
61                 final BigInteger tm = BigInteger.valueOf(tm1).add(BigInteger.valueOf(tm2)).divide(BigInteger.valueOf(2));
62                 final BigInteger nt = BigInteger.valueOf(nt1).add(BigInteger.valueOf(nt2)).divide(BigInteger.valueOf(2));
63
64                 nanoTimeOffset = tm.multiply(MILLION).subtract(nt);
65         }
66 }