BUG-7556: update version tracking
[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 com.google.common.base.Preconditions;
11
12 /**
13  * Local bucket implementation. Unlike a full-blown {@link Bucket}, this class is mutable and tracks when it has been
14  * changed and when it has been sent anywhere.
15  *
16  * @author Robert Varga
17  */
18 final class LocalBucket<T extends BucketData<T>> {
19     /*
20      * Decomposed 64bit signed version number. Always non-negative, hence the most significant bit is always zero.
21      * - incarnation number (most-significant 31 bits, forming an unsigned int)
22      * - version number (least-significant 32 bits, treated as unsigned int)
23      *
24      * We are keeping a boxed version here, as we stick it into a map anyway.
25      */
26     private Long version;
27     private T data;
28
29     // We bump versions only if we took a snapshot since last data update
30     private boolean bumpVersion;
31
32     LocalBucket(final int incarnation, final T data) {
33         Preconditions.checkArgument(incarnation >= 0);
34         this.version = ((long)incarnation) << Integer.SIZE;
35         this.data = Preconditions.checkNotNull(data);
36     }
37
38     T getData() {
39         return data;
40     }
41
42     Long getVersion() {
43         return version;
44     }
45
46     Bucket<T> snapshot() {
47         bumpVersion = true;
48         return new BucketImpl<>(version, data);
49     }
50
51     boolean setData(final T data) {
52         this.data = Preconditions.checkNotNull(data);
53         if (bumpVersion) {
54             final long next = version.longValue() + 1;
55             if ((next & 0xffff_ffffL) == 0) {
56                 return true;
57             }
58
59             version = next;
60             bumpVersion = false;
61         }
62         return false;
63     }
64 }