diff --git a/src/tracker/TrackerManagement.java b/src/tracker/TrackerManagement.java index 37c3cbc..b4a51fc 100644 --- a/src/tracker/TrackerManagement.java +++ b/src/tracker/TrackerManagement.java @@ -15,6 +15,8 @@ import protocolP2P.FileList; import protocolP2P.Unregister; import protocolP2P.Register; import protocolP2P.RequestResponseCode; +import protocolP2P.RatioRequest; +import protocolP2P.RatioResponse; import localException.InternalError; import remoteException.EmptyDirectory; import exception.LocalException; @@ -30,6 +32,8 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable protected HostItem tracker; protected Logger logger; protected List hostList = new ArrayList<>(); + protected Map ratioUp = new HashMap<>(); + protected Map ratioDown = new HashMap<>(); protected Map> fileList = new HashMap<>(); protected volatile boolean stop; @@ -62,6 +66,32 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable } } + + /** Handle Ratio request + * @param pd Received request + * @throws InternalError + */ + protected < T extends ProtocolP2PPacket > void handleRatio(T pd) throws InternalError { + Payload p = pd.getPayload(); + assert p instanceof RatioRequest : "payload must be an instance of RatioRequest"; + if (!(p instanceof RatioRequest)) { + sendInternalError(pd); + } else { + HostItem host = ((RatioRequest)p).getHostItem(); + try { + if (!hostList.contains(host)) { + pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.UNKNOWN_HOST))); + } else { + pd.sendResponse(createProtocolP2PPacket(new RatioResponse(host, + ratioUp.get(host).longValue(), + ratioDown.get(host).longValue()))); + } + } catch (Exception e) { + writeLog(e, LogLevel.Error); + } + } + } + /** Handle List Responses * @param pd Received response * @throws InternalError @@ -108,6 +138,10 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable fileList.remove(f); } } + + /* Note: we do not remove host from ratioUp and ratioDown since Unregistering is only here to indicate + * the host is temporary not serving any files (ie. is down). + */ } /** Getter for HostItem socket @@ -135,6 +169,14 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable if (!hostList.contains(host)) { hostList.add(host); } + + // initialize ratios if this is a new host + if (!ratioUp.containsKey(host)) { + ratioUp.put(host, Long.valueOf(0)); + } + if (!ratioDown.containsKey(host)) { + ratioDown.put(host, Long.valueOf(0)); + } // send a list request try { ProtocolP2PPacket pLReq = createProtocolP2PPacket(new Payload(RequestResponseCode.LIST_REQUEST)); @@ -186,6 +228,10 @@ public abstract class TrackerManagement extends ServeErrors implements Runnable writeLog("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action); handleDiscover(pd); break; + case RATIO_REQUEST: + writeLog("Received RATIO REQUEST from host " + pd.getHostItem(), LogLevel.Action); + handleRatio(pd); + break; default: writeLog("Received grabbage from host " + pd.getHostItem(), LogLevel.Action); sendInternalError(pd);