package com.tesora.dve.locking;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.net.InetSocketAddress;
public class IntentEntry implements Comparable<IntentEntry> {
public InetSocketAddress member;
public long published;
public long lastUnlockedOrAcquired;
public LockMode state;
public IntentEntry(InetSocketAddress member,LockMode state,long published) {
this(member,state,published,published);
}
public IntentEntry(InetSocketAddress member,LockMode state,long published, long lastUnlockedOrAcquired) {
this.member = member;
this.published = published;
this.lastUnlockedOrAcquired = lastUnlockedOrAcquired;
this.state = state;
}
public boolean isFor(InetSocketAddress myID) {
return this.member.equals(myID);
}
protected int comparePublishTime(IntentEntry someEntry) {
int compare = Long.compare(this.published,someEntry.published);
if (compare == 0)
compare = tiebreaker(this.member, someEntry.member);
return compare;
}
public boolean isPublishedBefore(IntentEntry someEntry) {
return comparePublishTime(someEntry) < 0;
}
public boolean isPublishedAfter(IntentEntry someEntry) {
return comparePublishTime(someEntry) > 0;
}
public boolean isEnteredBefore(IntentEntry other){
return this.lastUnlockedOrAcquired < other.lastUnlockedOrAcquired || (this.lastUnlockedOrAcquired == other.lastUnlockedOrAcquired && tiebreaker(this.member, other.member) < 0);
}
public boolean isAckedBy(IntentEntry entry){
return entry.published >= this.lastUnlockedOrAcquired;
}
public boolean isAnAcquire(){
return (state.isAcquiring());
}
public static int tiebreaker(InetSocketAddress addr1, InetSocketAddress addr2){
int compPort = Integer.compare(addr1.getPort(),addr2.getPort());
if (compPort != 0)
return compPort;
if (addr1.getAddress() == null){
if (addr2.getAddress() == null)
return 0;
else
return -1;
} else if (addr2.getAddress() == null)
return 1;
byte[] myBytes = addr1.getAddress().getAddress();
byte[] theirBytes = addr1.getAddress().getAddress();
if (myBytes.length < theirBytes.length)
return -1;
if (myBytes.length > theirBytes.length)
return 1;
for (int i=0;i<myBytes.length;i++){
int compByte = Byte.compare(myBytes[i],theirBytes[i]);
if (compByte != 0)
return compByte;
}
return 0;
}
public int compareTo(IntentEntry other){
int compET = Long.compare(this.lastUnlockedOrAcquired,other.lastUnlockedOrAcquired);
if (compET != 0)
return compET;
//tiebreaker. Only needs to make a given time distinct in a repeatable way, no other significance is assumed.
return tiebreaker(this.member, other.member);
}
public String toString(){
return String.format("IntentEntry[%s,%s,pub=%s,entry=%s]",member,state,published,lastUnlockedOrAcquired);
}
}