2 * Copyright 2015-present Open Networking Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.atomix.utils.time;
19 import com.google.common.base.MoreObjects;
20 import com.google.common.base.Objects;
21 import io.atomix.utils.misc.ArraySizeHashPrinter;
22 import io.atomix.utils.misc.TimestampPrinter;
24 import java.util.function.Function;
29 * @param <V> value type.
31 public class Versioned<V> {
32 private final V value;
33 private final long version;
34 private final long creationTime;
37 * Constructs a new versioned value.
40 * @param version version
41 * @param creationTime milliseconds of the creation event
42 * from the Java epoch of 1970-01-01T00:00:00Z
44 public Versioned(V value, long version, long creationTime) {
46 this.version = version;
47 this.creationTime = creationTime;
51 * Constructs a new versioned value.
54 * @param version version
56 public Versioned(V value, long version) {
57 this(value, version, System.currentTimeMillis());
70 * Returns the version.
74 public long version() {
79 * Returns the system time when this version was created.
81 * Care should be taken when relying on creationTime to
82 * implement any behavior in a distributed setting. Due
83 * to the possibility of clock skew it is likely that
84 * even creationTimes of causally related versions can be
87 * @return creation time
89 public long creationTime() {
94 * Maps this instance into another after transforming its
95 * value while retaining the same version and creationTime.
97 * @param transformer function for mapping the value
98 * @param <U> value type of the returned instance
99 * @return mapped instance
101 public synchronized <U> Versioned<U> map(Function<V, U> transformer) {
102 return new Versioned<>(value != null ? transformer.apply(value) : null, version, creationTime);
106 * Returns the value of the specified Versioned object if non-null or else returns
109 * @param versioned versioned object
110 * @param defaultValue default value to return if versioned object is null
111 * @param <U> type of the versioned value
112 * @return versioned value or default value if versioned object is null
114 public static <U> U valueOrElse(Versioned<U> versioned, U defaultValue) {
115 return versioned == null ? defaultValue : versioned.value();
119 * Returns the value of the specified Versioned object if non-null or else returns null.
121 * @param versioned versioned object
122 * @param <U> type of the versioned value
123 * @return versioned value or null if versioned object is null
125 public static <U> U valueOrNull(Versioned<U> versioned) {
126 return valueOrElse(versioned, null);
130 public int hashCode() {
131 return Objects.hashCode(value, version, creationTime);
135 public boolean equals(Object other) {
136 if (!(other instanceof Versioned)) {
139 Versioned<V> that = (Versioned) other;
140 return Objects.equal(this.value, that.value)
141 && Objects.equal(this.version, that.version)
142 && Objects.equal(this.creationTime, that.creationTime);
146 public String toString() {
147 return MoreObjects.toStringHelper(this)
148 .add("value", value instanceof byte[] ? ArraySizeHashPrinter.of((byte[]) value) : value)
149 .add("version", version)
150 .add("creationTime", new TimestampPrinter(creationTime))