aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Versioned.java
blob: 89bd30298e2a13026af49e3f61e29d64d6b952a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.store.service;

import java.util.function.Function;

import org.joda.time.DateTime;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;

/**
 * Versioned value.
 *
 * @param <V> value type.
 */
public class Versioned<V> {

    private final V value;
    private final long version;
    private final long creationTime;

    /**
     * Constructs a new versioned value.
     * @param value value
     * @param version version
     * @param creationTime milliseconds of the creation event
     *  from the Java epoch of 1970-01-01T00:00:00Z
     */
    public Versioned(V value, long version, long creationTime) {
        this.value = value;
        this.version = version;
        this.creationTime = creationTime;
    }

    /**
     * Constructs a new versioned value.
     * @param value value
     * @param version version
     */
    public Versioned(V value, long version) {
        this(value, version, System.currentTimeMillis());
    }

    /**
     * Returns the value.
     *
     * @return value.
     */
    public V value() {
        return value;
    }

    /**
     * Returns the version.
     *
     * @return version
     */
    public long version() {
        return version;
    }

    /**
     * Returns the system time when this version was created.
     * <p>
     * Care should be taken when relying on creationTime to
     * implement any behavior in a distributed setting. Due
     * to the possibility of clock skew it is likely that
     * even creationTimes of causally related versions can be
     * out or order.
     * @return creation time
     */
    public long creationTime() {
        return creationTime;
    }

    /**
     * Maps this instance into another after transforming its
     * value while retaining the same version and creationTime.
     * @param transformer function for mapping the value
     * @param <U> value type of the returned instance
     * @return mapped instance
     */
    public <U> Versioned<U> map(Function<V, U> transformer) {
        return new Versioned<>(transformer.apply(value), version, creationTime);
    }

    /**
     * Returns the value of the specified Versioned object if non-null or else returns
     * a default value.
     * @param versioned versioned object
     * @param defaultValue default value to return if versioned object is null
     * @param <U> type of the versioned value
     * @return versioned value or default value if versioned object is null
     */
    public static <U> U valueOrElse(Versioned<U> versioned, U defaultValue) {
        return versioned == null ? defaultValue : versioned.value();
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(value, version, creationTime);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Versioned)) {
            return false;
        }
        Versioned<V> that = (Versioned) other;
        return Objects.equal(this.value, that.value) &&
               Objects.equal(this.version, that.version) &&
               Objects.equal(this.creationTime, that.creationTime);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("value", value)
            .add("version", version)
            .add("creationTime", new DateTime(creationTime))
            .toString();
    }
}