Improve segmented journal actor metrics
[controller.git] / opendaylight / md-sal / sal-remoterpc-connector / src / main / java / org / opendaylight / controller / remote / rpc / registry / gossip / LocalBucket.java
1 /*
2  * Copyright (c) 2017 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.controller.remote.rpc.registry.gossip;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 /**
14  * Local bucket implementation. Unlike a full-blown {@link Bucket}, this class is mutable and tracks when it has been
15  * changed and when it has been sent anywhere.
16  *
17  * @author Robert Varga
18  */
19 final class LocalBucket<T extends BucketData<T>> {
20     /*
21      * Decomposed 64bit signed version number. Always non-negative, hence the most significant bit is always zero.
22      * - incarnation number (most-significant 31 bits, forming an unsigned int)
23      * - version number (least-significant 32 bits, treated as unsigned int)
24      *
25      * We are keeping a boxed version here, as we stick it into a map anyway.
26      */
27     private long version;
28     private T data;
29
30     // We bump versions only if we took a snapshot since last data update
31     private boolean bumpVersion;
32
33     LocalBucket(final int incarnation, final T data) {
34         checkArgument(incarnation >= 0);
35         this.version = (long)incarnation << Integer.SIZE;
36         this.data = requireNonNull(data);
37     }
38
39     T getData() {
40         return data;
41     }
42
43     long getVersion() {
44         return version;
45     }
46
47     Bucket<T> snapshot() {
48         bumpVersion = true;
49         return new BucketImpl<>(version, data);
50     }
51
52     boolean setData(final T newData) {
53         this.data = requireNonNull(newData);
54         if (!bumpVersion) {
55             return false;
56         }
57
58         bumpVersion = false;
59         return (++version & 0xffff_ffffL) == 0;
60     }
61 }