Package org.jmule.core.jkad.lookup

Source Code of org.jmule.core.jkad.lookup.LookupTask$RequestedContact

/*
*  JMule - Java file sharing client
*  Copyright (C) 2007-2009 JMule Team ( jmule@jmule.org / http://jmule.org )
*
*  Any parts of this program derived from other projects, or contributed
*  by third-party developers are copyrighted by their respective authors.
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  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 General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
*/
package org.jmule.core.jkad.lookup;

import static org.jmule.core.jkad.JKadConstants.ALPHA;
import static org.jmule.core.jkad.JKadConstants.INITIAL_LOOKUP_CONTACTS;
import static org.jmule.core.jkad.JKadConstants.LOOKUP_CONTACT_CHECK_INTERVAL;
import static org.jmule.core.jkad.JKadConstants.LOOKUP_CONTACT_TIMEOUT;
import static org.jmule.core.jkad.JKadConstants.LOOKUP_TASK_DEFAULT_TIMEOUT;
import static org.jmule.core.jkad.utils.Utils.getNearestContact;
import static org.jmule.core.jkad.utils.Utils.inToleranceZone;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import org.jmule.core.jkad.ContactAddress;
import org.jmule.core.jkad.Int128;
import org.jmule.core.jkad.InternalJKadManager;
import org.jmule.core.jkad.JKadManagerSingleton;
import org.jmule.core.jkad.JKadConstants.RequestType;
import org.jmule.core.jkad.packet.KadPacket;
import org.jmule.core.jkad.packet.PacketFactory;
import org.jmule.core.jkad.routingtable.KadContact;
import org.jmule.core.jkad.routingtable.RoutingTable;
import org.jmule.core.jkad.utils.Utils;
import org.jmule.core.jkad.utils.timer.Task;
import org.jmule.core.jkad.utils.timer.Timer;
import org.jmule.core.networkmanager.InternalNetworkManager;
import org.jmule.core.networkmanager.NetworkManagerSingleton;

/**
* Created on Jan 9, 2009
* @author binary256
* @version $Revision: 1.7 $
* Last changed by $Author: binary255 $ on $Date: 2010/01/13 18:42:15 $
*/
public abstract class LookupTask {
 
  protected int initialLookupContacts;
  protected long responseTime;
  protected Int128 targetID;
  protected long toleranceZone;
  protected long timeOut =  LOOKUP_TASK_DEFAULT_TIMEOUT;
 
  protected List<KadContact> possibleContacts = new Vector<KadContact> ();
  protected List<KadContact> usedContacts = new Vector<KadContact>();
  protected Map<ContactAddress, RequestedContact> requestedContacts = new ConcurrentHashMap<ContactAddress, RequestedContact>();
 
  protected RoutingTable routingTable;
  protected RequestType requestType;
 
  protected Task contactCleaner = null;
 
  protected boolean lookupStarted = false;
 
  protected InternalNetworkManager _network_manager;
  protected InternalJKadManager    _jkad_manager;
 
  protected long startTime = 0;
 
  public long getStartTime() {
    return startTime;
  }
 
  public LookupTask(RequestType requestType, Int128 targetID, long toleranceZone) {
    this(requestType, targetID, toleranceZone, INITIAL_LOOKUP_CONTACTS);
  }
 
  public LookupTask(RequestType requestType, Int128 targetID, long toleranceZone, int initialLookupContacts) {
    this.startTime = System.currentTimeMillis();
    this.targetID = targetID;
    this.toleranceZone = toleranceZone;
 
    this.requestType = requestType;
    this.initialLookupContacts = initialLookupContacts;
    responseTime = System.currentTimeMillis();
    routingTable = RoutingTable.getSingleton();
   
    _network_manager = (InternalNetworkManager) NetworkManagerSingleton.getInstance();
    _jkad_manager    = (InternalJKadManager) JKadManagerSingleton.getInstance();
  }
 
  public void startLookup() {
    lookupStarted = true;
    responseTime = System.currentTimeMillis();
    possibleContacts.addAll(routingTable.getNearestContacts(targetID, initialLookupContacts));
   
       
    int count = ALPHA;
    if (count > possibleContacts.size()) count = possibleContacts.size();
    for (int i = 0; i < count; i++) {
      KadContact contact = getNearestContact(Utils.XOR(targetID,_jkad_manager.getClientID()), possibleContacts,usedContacts);
     
      lookupContact(contact);
    }
   
    contactCleaner = new Task() {
      public void run() {
        for(ContactAddress address : requestedContacts.keySet()) {
          RequestedContact c = requestedContacts.get(address);
          if (c==null) { requestedContacts.remove(address); continue; }
          if (System.currentTimeMillis() - c.getRequestTime() > LOOKUP_CONTACT_TIMEOUT) {
            requestedContacts.remove(address);
            // lookup next
            KadContact contact = getNearestContact(Utils.XOR(targetID,_jkad_manager.getClientID()), possibleContacts,usedContacts);
            if (contact == null) return;
            lookupContact(contact);
          }
        }
           
      }
    };
   
    Timer.getSingleton().addTask(LOOKUP_CONTACT_CHECK_INTERVAL, contactCleaner, true);
  }
 
  public void stopLookup() {
    stopLookupEvent();
    lookupStarted = false;
   
    Timer.getSingleton().removeTask(contactCleaner);
    possibleContacts.clear();
    usedContacts.clear();
    requestedContacts.clear();
  }
 
  public abstract void stopLookupEvent();
 
  public void  processResults(ContactAddress sender, List<KadContact> results) {
    responseTime = System.currentTimeMillis();
   
    List<KadContact> alpha  = new LinkedList<KadContact>();
   
    for(KadContact contact : results) {
      if (usedContacts.contains(contact)) continue;
      if (possibleContacts.contains(contact)) continue;     
      if (inToleranceZone(Utils.XOR(contact.getContactID(), _jkad_manager.getClientID()), Utils.XOR(targetID, _jkad_manager.getClientID()), toleranceZone)) {

        alpha.add(contact);
      }
      else
        possibleContacts.add(contact);
    }
    if (alpha.size()!=0) {
     
      processToleranceContacts(sender, alpha);
    }
   
    requestedContacts.remove(sender);
    KadContact contact = getNearestContact(Utils.XOR(targetID, _jkad_manager.getClientID()), possibleContacts,usedContacts);
    if (contact != null) lookupContact(contact);

  }
 
  private void lookupContact(KadContact contact) {
    possibleContacts.remove(contact);
    usedContacts.add(contact);
    RequestedContact requested_contact = new RequestedContact(contact, System.currentTimeMillis());
   
    requestedContacts.put(contact.getContactAddress(), requested_contact);
    KadPacket packet;
    //if (contact.getVersion()>=2)/*47a*/
    //  packet = PacketFactory.getRequest2Packet(requestType, targetID, (Int128)contact.getContactID());
    //else
      packet = PacketFactory.getRequestPacket(requestType, targetID, (Int128)contact.getContactID());
    _network_manager.sendKadPacket(packet, contact.getIPAddress(), contact.getUDPPort());
  }
 
  public long getResponseTime() {
    return responseTime;
  }
  public void setResponseTime(long responseTime) {
    this.responseTime = responseTime;
  }
 
  public Int128 getTargetID() {
    return targetID;
  }
  public void setTargetID(Int128 targetID) {
    this.targetID = targetID;
  }

  public long getTimeOut() {
    return timeOut;
  }

  public void setTimeOut(long timeOut) {
    this.timeOut = timeOut;
  }
 

  public long getToleranceZone() {
    return toleranceZone;
  }

  public void setToleranceZone(long toleranceZone) {
    this.toleranceZone = toleranceZone;
  };
 
  /**
   * Lookup process timeout
   */
  public abstract void lookupTimeout();
 
  /**
   * Process tolerance contacts
   * @param sender
   * @param results
   */
  public abstract void processToleranceContacts(ContactAddress sender, List<KadContact> results);
 
  protected class RequestedContact {
    private KadContact contact;
    private long requestTime;
   
    public RequestedContact(KadContact contact, long requestTime) {
      super();
      this.contact = contact;
      this.requestTime = requestTime;
    }

    public KadContact getContact() {
      return contact;
    }

    public void setContact(KadContact contact) {
      this.contact = contact;
    }

    public long getRequestTime() {
      return requestTime;
    }
   
  }

  public boolean isLookupStarted() {
    return lookupStarted;
  }

  public RequestType getRequestType() {
    return requestType;
  }
}
TOP

Related Classes of org.jmule.core.jkad.lookup.LookupTask$RequestedContact

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.