Import atomix/{storage,utils}
[controller.git] / third-party / atomix / utils / src / main / java / io / atomix / utils / time / VectorClock.java
1 /*
2  * Copyright 2017-present Open Networking Foundation
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package io.atomix.utils.time;
17
18 import com.google.common.annotations.Beta;
19 import io.atomix.utils.Identifier;
20
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import static com.google.common.base.MoreObjects.toStringHelper;
27
28 /**
29  * Vector clock.
30  */
31 @Beta
32 public class VectorClock<T extends Identifier> implements Clock<VectorTimestamp<T>> {
33   private final T localIdentifier;
34   private final Map<T, VectorTimestamp<T>> vector = new HashMap<>();
35
36   public VectorClock(T localIdentifier) {
37     this(new VectorTimestamp<T>(localIdentifier, 0));
38   }
39
40   public VectorClock(VectorTimestamp<T> localTimestamp) {
41     this(localTimestamp, Collections.emptyList());
42   }
43
44   public VectorClock(VectorTimestamp<T> localTimestamp, Collection<VectorTimestamp<T>> vector) {
45     this.localIdentifier = localTimestamp.identifier();
46     this.vector.put(localTimestamp.identifier(), localTimestamp);
47     for (VectorTimestamp<T> timestamp : vector) {
48       this.vector.put(timestamp.identifier(), timestamp);
49     }
50   }
51
52   @Override
53   public VectorTimestamp<T> getTime() {
54     return vector.get(localIdentifier);
55   }
56
57   /**
58    * Returns the local logical timestamp.
59    *
60    * @return the logical timestamp for the local identifier
61    */
62   public LogicalTimestamp getLocalTimestamp() {
63     return getTime();
64   }
65
66   /**
67    * Returns the logical timestamp for the given identifier.
68    *
69    * @param identifier the identifier for which to return the timestamp
70    * @return the logical timestamp for the given identifier
71    */
72   public LogicalTimestamp getTimestamp(T identifier) {
73     return vector.get(identifier);
74   }
75
76   /**
77    * Returns a collection of identifier-timestamp pairs.
78    *
79    * @return a collection of identifier-timestamp pairs
80    */
81   public Collection<VectorTimestamp<T>> getTimestamps() {
82     return vector.values();
83   }
84
85   /**
86    * Updates the given timestamp.
87    *
88    * @param timestamp the timestamp to update
89    */
90   public void update(VectorTimestamp<T> timestamp) {
91     VectorTimestamp<T> currentTimestamp = vector.get(timestamp.identifier());
92     if (currentTimestamp == null || currentTimestamp.value() < timestamp.value()) {
93       vector.put(timestamp.identifier(), timestamp);
94     }
95   }
96
97   /**
98    * Updates the vector clock.
99    *
100    * @param clock the vector clock with which to update this clock
101    */
102   public void update(VectorClock<T> clock) {
103     for (VectorTimestamp<T> timestamp : clock.vector.values()) {
104       update(timestamp);
105     }
106   }
107
108   @Override
109   public String toString() {
110     return toStringHelper(this)
111         .add("time", getTime())
112         .add("vector", getTimestamps())
113         .toString();
114   }
115 }