Refactor ClientVersion to bramble-api.

This commit is contained in:
akwizgran
2019-10-09 17:48:58 +01:00
parent 75dfa80541
commit a844526dae
2 changed files with 109 additions and 80 deletions

View File

@@ -0,0 +1,63 @@
package org.briarproject.bramble.api.versioning;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class ClientVersion implements Comparable<ClientVersion> {
private final ClientMajorVersion majorVersion;
private final int minorVersion;
public ClientVersion(ClientMajorVersion majorVersion,
int minorVersion) {
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
}
public ClientVersion(ClientId clientId, int majorVersion,
int minorVersion) {
this(new ClientMajorVersion(clientId, majorVersion), minorVersion);
}
public ClientMajorVersion getClientMajorVersion() {
return majorVersion;
}
public ClientId getClientId() {
return majorVersion.getClientId();
}
public int getMajorVersion() {
return majorVersion.getMajorVersion();
}
public int getMinorVersion() {
return minorVersion;
}
@Override
public boolean equals(Object o) {
if (o instanceof ClientVersion) {
ClientVersion cv = (ClientVersion) o;
return majorVersion.equals(cv.majorVersion)
&& minorVersion == cv.minorVersion;
}
return false;
}
@Override
public int hashCode() {
return majorVersion.hashCode();
}
@Override
public int compareTo(ClientVersion cv) {
int compare = majorVersion.compareTo(cv.majorVersion);
if (compare != 0) return compare;
return minorVersion - cv.minorVersion;
}
}

View File

@@ -26,6 +26,7 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook; import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientMajorVersion; import org.briarproject.bramble.api.versioning.ClientMajorVersion;
import org.briarproject.bramble.api.versioning.ClientVersion;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import java.util.ArrayList; import java.util.ArrayList;
@@ -80,9 +81,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
@Override @Override
public void registerClient(ClientId clientId, int majorVersion, public void registerClient(ClientId clientId, int majorVersion,
int minorVersion, ClientVersioningHook hook) { int minorVersion, ClientVersioningHook hook) {
ClientMajorVersion cv = new ClientMajorVersion(clientId, majorVersion); ClientMajorVersion cmv = new ClientMajorVersion(clientId, majorVersion);
clients.add(new ClientVersion(cv, minorVersion)); clients.add(new ClientVersion(cmv, minorVersion));
hooks.put(cv, hook); hooks.put(cmv, hook);
} }
@Override @Override
@@ -96,9 +97,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId); Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
Map<ClientMajorVersion, Visibility> visibilities = Map<ClientMajorVersion, Visibility> visibilities =
getVisibilities(localUpdate.states, remoteUpdate.states); getVisibilities(localUpdate.states, remoteUpdate.states);
ClientMajorVersion cv = ClientMajorVersion key =
new ClientMajorVersion(clientId, majorVersion); new ClientMajorVersion(clientId, majorVersion);
Visibility v = visibilities.get(cv); Visibility v = visibilities.get(key);
return v == null ? INVISIBLE : v; return v == null ? INVISIBLE : v;
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
@@ -112,10 +113,11 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
LatestUpdates latest = findLatestUpdates(txn, contactId); LatestUpdates latest = findLatestUpdates(txn, contactId);
if (latest == null || latest.remote == null) return -1; if (latest == null || latest.remote == null) return -1;
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId); Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
ClientMajorVersion cv = ClientMajorVersion key =
new ClientMajorVersion(clientId, majorVersion); new ClientMajorVersion(clientId, majorVersion);
for (ClientState remote : remoteUpdate.states) { for (ClientState remote : remoteUpdate.states) {
if (remote.majorVersion.equals(cv)) return remote.minorVersion; if (remote.clientVersion.getClientMajorVersion().equals(key))
return remote.clientVersion.getMinorVersion();
} }
return -1; return -1;
} catch (FormatException e) { } catch (FormatException e) {
@@ -256,8 +258,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
} }
private BdfList encodeClientVersion(ClientVersion cv) { private BdfList encodeClientVersion(ClientVersion cv) {
return BdfList.of(cv.majorVersion.getClientId().getString(), return BdfList.of(cv.getClientId().getString(), cv.getMajorVersion(),
cv.majorVersion.getMajorVersion(), cv.minorVersion); cv.getMinorVersion());
} }
/** /**
@@ -298,8 +300,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
ClientId clientId = new ClientId(cv.getString(0)); ClientId clientId = new ClientId(cv.getString(0));
int majorVersion = cv.getLong(1).intValue(); int majorVersion = cv.getLong(1).intValue();
int minorVersion = cv.getLong(2).intValue(); int minorVersion = cv.getLong(2).intValue();
parsed.add(new ClientVersion(clientId, majorVersion, parsed.add(new ClientVersion(clientId, majorVersion, minorVersion));
minorVersion));
} }
return parsed; return parsed;
} }
@@ -418,13 +419,15 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
private List<ClientState> updateStatesFromLocalVersions( private List<ClientState> updateStatesFromLocalVersions(
List<ClientState> oldStates, List<ClientVersion> newVersions) { List<ClientState> oldStates, List<ClientVersion> newVersions) {
Map<ClientMajorVersion, ClientState> oldMap = new HashMap<>(); Map<ClientMajorVersion, ClientState> oldMap = new HashMap<>();
for (ClientState cs : oldStates) oldMap.put(cs.majorVersion, cs); for (ClientState cs : oldStates) {
oldMap.put(cs.clientVersion.getClientMajorVersion(), cs);
}
List<ClientState> newStates = new ArrayList<>(newVersions.size()); List<ClientState> newStates = new ArrayList<>(newVersions.size());
for (ClientVersion newVersion : newVersions) { for (ClientVersion newVersion : newVersions) {
ClientState oldState = oldMap.get(newVersion.majorVersion); ClientMajorVersion key = newVersion.getClientMajorVersion();
ClientState oldState = oldMap.get(key);
boolean active = oldState != null && oldState.active; boolean active = oldState != null && oldState.active;
newStates.add(new ClientState(newVersion.majorVersion, newStates.add(new ClientState(newVersion, active));
newVersion.minorVersion, active));
} }
return newStates; return newStates;
} }
@@ -451,21 +454,25 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
} }
private BdfList encodeClientState(ClientState cs) { private BdfList encodeClientState(ClientState cs) {
return BdfList.of(cs.majorVersion.getClientId().getString(), ClientVersion cv = cs.clientVersion;
cs.majorVersion.getMajorVersion(), cs.minorVersion, cs.active); return BdfList.of(cv.getClientId().getString(), cv.getMajorVersion(),
cv.getMinorVersion(), cs.active);
} }
private Map<ClientMajorVersion, Visibility> getVisibilities( private Map<ClientMajorVersion, Visibility> getVisibilities(
List<ClientState> localStates, List<ClientState> remoteStates) { List<ClientState> localStates, List<ClientState> remoteStates) {
Map<ClientMajorVersion, ClientState> remoteMap = new HashMap<>(); Map<ClientMajorVersion, ClientState> remoteMap = new HashMap<>();
for (ClientState cs : remoteStates) remoteMap.put(cs.majorVersion, cs); for (ClientState cs : remoteStates) {
remoteMap.put(cs.clientVersion.getClientMajorVersion(), cs);
}
Map<ClientMajorVersion, Visibility> visibilities = new HashMap<>(); Map<ClientMajorVersion, Visibility> visibilities = new HashMap<>();
for (ClientState local : localStates) { for (ClientState local : localStates) {
ClientState remote = remoteMap.get(local.majorVersion); ClientMajorVersion key =
if (remote == null) visibilities.put(local.majorVersion, INVISIBLE); local.clientVersion.getClientMajorVersion();
else if (remote.active) ClientState remote = remoteMap.get(key);
visibilities.put(local.majorVersion, SHARED); if (remote == null) visibilities.put(key, INVISIBLE);
else visibilities.put(local.majorVersion, VISIBLE); else if (remote.active) visibilities.put(key, SHARED);
else visibilities.put(key, VISIBLE);
} }
return visibilities; return visibilities;
} }
@@ -486,9 +493,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
} }
} }
private void callVisibilityHook(Transaction txn, ClientMajorVersion cv, private void callVisibilityHook(Transaction txn, ClientMajorVersion cmv,
Contact c, Visibility v) throws DbException { Contact c, Visibility v) throws DbException {
ClientVersioningHook hook = hooks.get(cv); ClientVersioningHook hook = hooks.get(cmv);
if (hook != null) hook.onClientVisibilityChanging(txn, c, v); if (hook != null) hook.onClientVisibilityChanging(txn, c, v);
} }
@@ -496,8 +503,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
List<ClientVersion> versions) throws DbException { List<ClientVersion> versions) throws DbException {
List<ClientState> states = new ArrayList<>(versions.size()); List<ClientState> states = new ArrayList<>(versions.size());
for (ClientVersion cv : versions) { for (ClientVersion cv : versions) {
states.add(new ClientState(cv.majorVersion, cv.minorVersion, states.add(new ClientState(cv, false));
false));
} }
storeUpdate(txn, g, states, 1); storeUpdate(txn, g, states, 1);
} }
@@ -516,13 +522,16 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
private List<ClientState> updateStatesFromRemoteStates( private List<ClientState> updateStatesFromRemoteStates(
List<ClientState> oldLocalStates, List<ClientState> remoteStates) { List<ClientState> oldLocalStates, List<ClientState> remoteStates) {
Set<ClientMajorVersion> remoteSet = new HashSet<>(); Set<ClientMajorVersion> remoteSet = new HashSet<>();
for (ClientState cs : remoteStates) remoteSet.add(cs.majorVersion); for (ClientState cs : remoteStates) {
remoteSet.add(cs.clientVersion.getClientMajorVersion());
}
List<ClientState> newLocalStates = List<ClientState> newLocalStates =
new ArrayList<>(oldLocalStates.size()); new ArrayList<>(oldLocalStates.size());
for (ClientState oldState : oldLocalStates) { for (ClientState oldState : oldLocalStates) {
boolean active = remoteSet.contains(oldState.majorVersion); ClientMajorVersion cmv =
newLocalStates.add(new ClientState(oldState.majorVersion, oldState.clientVersion.getClientMajorVersion();
oldState.minorVersion, active)); boolean active = remoteSet.contains(cmv);
newLocalStates.add(new ClientState(oldState.clientVersion, active));
} }
return newLocalStates; return newLocalStates;
} }
@@ -561,61 +570,19 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
} }
} }
private static class ClientVersion implements Comparable<ClientVersion> {
private final ClientMajorVersion majorVersion;
private final int minorVersion;
private ClientVersion(ClientMajorVersion majorVersion,
int minorVersion) {
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
}
private ClientVersion(ClientId clientId, int majorVersion,
int minorVersion) {
this(new ClientMajorVersion(clientId, majorVersion), minorVersion);
}
@Override
public boolean equals(Object o) {
if (o instanceof ClientVersion) {
ClientVersion cv = (ClientVersion) o;
return majorVersion.equals(cv.majorVersion)
&& minorVersion == cv.minorVersion;
}
return false;
}
@Override
public int hashCode() {
return majorVersion.hashCode();
}
@Override
public int compareTo(ClientVersion cv) {
int compare = majorVersion.compareTo(cv.majorVersion);
if (compare != 0) return compare;
return minorVersion - cv.minorVersion;
}
}
private static class ClientState { private static class ClientState {
private final ClientMajorVersion majorVersion; private final ClientVersion clientVersion;
private final int minorVersion;
private final boolean active; private final boolean active;
private ClientState(ClientMajorVersion majorVersion, int minorVersion, private ClientState(ClientVersion clientVersion, boolean active) {
boolean active) { this.clientVersion = clientVersion;
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
this.active = active; this.active = active;
} }
private ClientState(ClientId clientId, int majorVersion, private ClientState(ClientId clientId, int majorVersion,
int minorVersion, boolean active) { int minorVersion, boolean active) {
this(new ClientMajorVersion(clientId, majorVersion), minorVersion, this(new ClientVersion(clientId, majorVersion, minorVersion),
active); active);
} }
@@ -623,8 +590,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof ClientState) { if (o instanceof ClientState) {
ClientState cs = (ClientState) o; ClientState cs = (ClientState) o;
return majorVersion.equals(cs.majorVersion) return clientVersion.equals(cs.clientVersion)
&& minorVersion == cs.minorVersion
&& active == cs.active; && active == cs.active;
} }
return false; return false;
@@ -632,7 +598,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
@Override @Override
public int hashCode() { public int hashCode() {
return majorVersion.hashCode(); return clientVersion.hashCode();
} }
} }
} }