Madan Jampani

Added a WallClockTimestamp and associated interface/implementation for generatin…

…g it. This will be used by the initial implementation of distributed host store
package org.onlab.onos.net.host;
import org.onlab.onos.store.Timestamp;
import org.onlab.packet.MacAddress;
/**
* Interface for a logical clock service that issues per host timestamps.
*/
public interface HostClockService {
/**
* Returns a new timestamp for the specified host mac address.
* @param hostMac host MAC address.
* @return timestamp.
*/
public Timestamp getTimestamp(MacAddress hostMac);
}
package org.onlab.onos.store.host.impl;
import static org.slf4j.LoggerFactory.getLogger;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.net.host.HostClockService;
import org.onlab.onos.store.Timestamp;
import org.onlab.onos.store.impl.WallClockTimestamp;
import org.onlab.packet.MacAddress;
import org.slf4j.Logger;
/**
* HostClockService to issue Timestamps based on local wallclock time.
*/
@Component(immediate = true)
@Service
public class HostClockManager implements HostClockService {
private final Logger log = getLogger(getClass());
@Activate
public void activate() {
log.info("Started");
}
@Deactivate
public void deactivate() {
log.info("Stopped");
}
@Override
public Timestamp getTimestamp(MacAddress hostMac) {
return new WallClockTimestamp();
}
}
......@@ -10,8 +10,12 @@ import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
/**
* Default implementation of Timestamp.
* TODO: Better documentation.
* A logical timestamp that derives its value from two things:
* <ul>
* <li> The current mastership term of the device.</li>
* <li> The value of the counter used for tracking topology events observed from
* the device during that current time of a device. </li>
* </ul>
*/
public final class MastershipBasedTimestamp implements Timestamp {
......
package org.onlab.onos.store.impl;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Objects;
import org.onlab.onos.store.Timestamp;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
/**
* A Timestamp that derives its value from the prevailing
* wallclock time on the controller where it is generated.
*/
public class WallClockTimestamp implements Timestamp {
private final long unixTimestamp;
public WallClockTimestamp() {
unixTimestamp = System.currentTimeMillis();
}
@Override
public int compareTo(Timestamp o) {
checkArgument(o instanceof WallClockTimestamp,
"Must be WallClockTimestamp", o);
WallClockTimestamp that = (WallClockTimestamp) o;
return ComparisonChain.start()
.compare(this.unixTimestamp, that.unixTimestamp)
.result();
}
@Override
public int hashCode() {
return Objects.hash(unixTimestamp);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof WallClockTimestamp)) {
return false;
}
WallClockTimestamp that = (WallClockTimestamp) obj;
return Objects.equals(this.unixTimestamp, that.unixTimestamp);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("unixTimestamp", unixTimestamp)
.toString();
}
/**
* Returns the unixTimestamp.
*
* @return unix timestamp
*/
public long unixTimestamp() {
return unixTimestamp;
}
}
package org.onlab.onos.store.impl;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import org.junit.Test;
import org.onlab.onos.store.Timestamp;
import org.onlab.util.KryoPool;
import com.google.common.testing.EqualsTester;
/**
* Tests for {@link WallClockTimestamp}.
*/
public class WallClockTimestampTest {
@Test
public final void testBasic() throws InterruptedException {
WallClockTimestamp ts1 = new WallClockTimestamp();
Thread.sleep(50);
WallClockTimestamp ts2 = new WallClockTimestamp();
assertTrue(ts1.compareTo(ts1) == 0);
assertTrue(ts2.compareTo(ts1) > 0);
assertTrue(ts1.compareTo(ts2) < 0);
}
@Test
public final void testKryoSerializable() {
WallClockTimestamp ts1 = new WallClockTimestamp();
final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024);
final KryoPool kryos = KryoPool.newBuilder()
.register(WallClockTimestamp.class)
.build();
kryos.serialize(ts1, buffer);
buffer.flip();
Timestamp copy = kryos.deserialize(buffer);
new EqualsTester()
.addEqualityGroup(ts1, copy)
.testEquals();
}
}