RoutingTable.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
xnap.plugin.gnutella.net |
![]() |
![]() |
XNap 2 |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* 03/31/2001
*
* RoutingTable.java
* Copyright (C) 2001 Frederik Zimmer
* tristian@users.sourceforge.net
* http://sourceforge.net/projects/ziga/
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package xnap.plugin.gnutella.net;
import xnap.util.*;
import xnap.util.event.*;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
public class RoutingTable implements ListListener
{
//--- Data field(s) ---
protected Connections connections = Connections.getInstance();
protected static HashMap pongRoutingTable = new HashMap(4000);
protected static HashMap queryhitRoutingTable = new HashMap(10000);
protected static HashMap pushRoutingTable = new HashMap(5000);
protected static HashMap activeSearches = new HashMap();
protected RoutingTableCleaner routingTableCleaner;
private static RoutingTable instance = null;
private RoutingTable()
{
connections.addListListener(this);
routingTableCleaner = new RoutingTableCleaner();
routingTableCleaner.start();
}
public synchronized static RoutingTable getInstance()
{
if (instance == null) {
instance = new RoutingTable();
}
return instance;
}
public void send(PingMessage msg, Servent con)
{
con.send(msg, Servent.PRIORITY_NORMAL);
synchronized(pongRoutingTable) {
pongRoutingTable.put(msg.getMessageID(),
new PingMessageEntry(null));
}
}
public void route(PingMessage msg, Servent con)
{
if (msg.getTTL() <= 0) {
return;
}
msg.decrementTTL();
GUID id = msg.getMessageID();
synchronized(pongRoutingTable) {
if (pongRoutingTable.containsKey(id)) {
return;
}
pongRoutingTable.put(id, new PingMessageEntry(con));
}
connections.sendPong(msg, con);
if (msg.getTTL() > 0) {
connections.broadcastMessage(msg, con);
}
}
public void route(PongMessage msg, Servent con)
{
PingMessageEntry entry;
msg.decrementTTL();
connections.incomingPong(msg);
if (msg.getTTL() <= 0)
return;
synchronized(pongRoutingTable) {
entry =
(PingMessageEntry) pongRoutingTable.get(msg.getMessageID());
}
if (entry == null)
return;
entry.hit();
if (!entry.alreadySeenPongMessage(msg)) {
Servent servent = entry.getSource();
if (servent != null) {
servent.send(msg, Servent.PRIORITY_ROUTE);
}
}
}
public void send(QueryMessage msg)
{
synchronized(queryhitRoutingTable) {
queryhitRoutingTable.put(msg.getMessageID(),
new QueryMessageEntry(msg.getMessageID()));
}
connections.sendMessage(msg);
}
public void send(QueryMessage msg, Servent servent)
{
synchronized(queryhitRoutingTable) {
queryhitRoutingTable.put(msg.getMessageID(),
new QueryMessageEntry(msg.getMessageID()));
}
servent.send(msg, Servent.PRIORITY_NORMAL);
}
public void route(IndexingQueryMessage msg, Servent servent)
{
synchronized(queryhitRoutingTable) {
queryhitRoutingTable.put(msg.getMessageID(),
new QueryMessageEntry(msg.getMessageID()));
}
servent.send(msg, Servent.PRIORITY_NORMAL);
}
public void route(QueryMessage msg, Servent servent)
{
msg.decrementTTL();
if (msg.getTTL() <= 0)
return;
GUID id = msg.getMessageID();
synchronized(queryhitRoutingTable) {
if (queryhitRoutingTable.containsKey(id)) {
return;
}
else {
queryhitRoutingTable.put(id, new QueryMessageEntry(servent));
}
}
connections.broadcastMessage(msg, servent);
connections.searchRepository(msg, servent);
}
public void route(QueryHitMessage msg)
{
QueryMessageEntry entry;
synchronized(queryhitRoutingTable) {
entry = (QueryMessageEntry)
queryhitRoutingTable.get(msg.getMessageID());
}
if (entry == null)
return;
entry.hit();
synchronized(pushRoutingTable) {
pushRoutingTable.put(msg.getServentID(),
new QueryHitMessageEntry(null));
}
Servent servent = entry.getSource();
if (servent != null) {
servent.send(msg, Servent.PRIORITY_ROUTE);
}
}
public void route(QueryHitMessage msg, Servent servent)
{
QueryMessageEntry entry;
if (msg.getTTL() <= 0)
return;
msg.decrementTTL();
synchronized(queryhitRoutingTable) {
entry = (QueryMessageEntry)
queryhitRoutingTable.get(msg.getMessageID());
}
if (entry == null)
return;
entry.hit();
GUID id = msg.getMessageID();
synchronized(pushRoutingTable) {
if (pushRoutingTable.containsKey(id)) {
return;
}
pushRoutingTable.put(msg.getServentID(),
new QueryHitMessageEntry(servent));
}
Servent s = entry.getSource();
if (s != null) {
if (msg.getTTL() > 0) {
s.send(msg, Servent.PRIORITY_ROUTE);
}
}
else {
Search search =
(Search) activeSearches.get(msg.getMessageID());
if (search != null) {
addResults(search, msg, servent);
}
}
}
public boolean route(PushMessage msg)
{
QueryHitMessageEntry entry;
synchronized(pushRoutingTable) {
entry = (QueryHitMessageEntry)
pushRoutingTable.get(msg.getServentID());
}
if (entry != null) {
Servent servent = entry.getSource();
if (servent != null) {
servent.send(msg, Servent.PRIORITY_ROUTE);
return true;
}
}
return false;
}
public void route(PushMessage msg, Servent con)
{
QueryHitMessageEntry entry;
msg.decrementTTL();
if (msg.getTTL() <= 0)
return;
synchronized(pushRoutingTable) {
entry = (QueryHitMessageEntry)
pushRoutingTable.get(msg.getServentID());
}
if (entry != null) {
Servent tmpCon = entry.getSource();
if (tmpCon != null) {
tmpCon.send(msg, Servent.PRIORITY_ROUTE);
}
else {
// someone requests a firewalled upload
// Upload u = new FirewalledUpload(msg);
// UploadQueue.getInstance().add(u);
}
}
}
public void removeServent(Servent servent)
{
synchronized(pushRoutingTable) {
Iterator i = pushRoutingTable.values().iterator();
while (i.hasNext()) {
QueryHitMessageEntry me = (QueryHitMessageEntry) i.next();
if (me.getSource() == servent) {
i.remove();
}
}
}
}
private void addResults(Search search, QueryHitMessage msg,
Servent servent)
{
ResultSet[] set = msg.getResults();
for (int i = 0; i < set.length; i++) {
search.add(new SearchResult(set[i].getSize(),
set[i].getFilename(),
msg.getIP(), msg.getPort(),
set[i].getIndex(), servent,
msg.getServentID()));
}
}
public void startSearch(QueryMessage msg, Search search)
{
activeSearches.put(msg.getMessageID(), search);
send(msg);
}
public void stopSearch(QueryMessage msg)
{
activeSearches.remove(msg.getMessageID());
}
public void elementAdded(ListEvent event)
{
/* not needed yet */
}
public void elementRemoved(ListEvent event)
{
Servent servent = (Servent) event.getElement();
removeServent(servent);
}
/* private classes */
protected class MessageEntry
{
protected long creationTime;
MessageEntry()
{
creationTime = System.currentTimeMillis();
}
public void hit()
{
creationTime = System.currentTimeMillis();
}
}
private class PingMessageEntry extends MessageEntry
{
private Servent servent;
private Vector entries = new Vector();
PingMessageEntry(Servent servent)
{
this.servent = servent;
}
boolean alreadySeenPongMessage(PongMessage msg)
{
if (entries.contains(msg)) {
return true;
}
else {
entries.addElement(msg);
return false;
}
}
Servent getSource() {
return servent;
}
}
private class QueryMessageEntry extends MessageEntry
{
private Servent servent;
private GUID guid;
QueryMessageEntry(Servent servent)
{
this.servent = servent;
guid = null;
}
QueryMessageEntry(GUID guid)
{
this.guid = guid;
servent = null;
}
Servent getSource()
{
return servent;
}
GUID getGUID() {
return guid;
}
}
private class QueryHitMessageEntry extends MessageEntry
{
private Servent servent;
QueryHitMessageEntry(Servent servent)
{
this.servent = servent;
}
Servent getSource()
{
return servent;
}
}
private class SearchEntry
{
public Search search;
public long creationTime;
SearchEntry(Search search)
{
this.search = search;
creationTime = System.currentTimeMillis();
}
public void hit()
{
creationTime = System.currentTimeMillis();
}
}
protected class RoutingTableCleaner implements Runnable
{
protected static final int SLEEPTIME = 30 * 1000;
protected static final int PING_LIFETIME = 120000;
protected static final int QUERY_LIFETIME = 180 * 1000;
protected static final int QUERY_HIT_LIFETIME = 1800 * 1000;
protected static final int SEARCH_LIFETIME = 60 * 1000;
protected boolean alive;
protected Thread thread;
public synchronized void start()
{
if (!alive) {
alive = true;
thread = new Thread(this);
thread.start();
}
}
public void run()
{
while (alive) {
try {
thread.sleep(SLEEPTIME);
}
catch(InterruptedException e) {
}
long time = System.currentTimeMillis();
synchronized(pongRoutingTable) {
Iterator i = pongRoutingTable.values().iterator();
while (i.hasNext()) {
MessageEntry me = (MessageEntry) i.next();
if (time - me.creationTime > PING_LIFETIME) {
i.remove();
}
}
}
synchronized(queryhitRoutingTable) {
Iterator i = queryhitRoutingTable.values().iterator();
while (i.hasNext()) {
QueryMessageEntry qme = (QueryMessageEntry) i.next();
if (time - qme.creationTime > QUERY_LIFETIME) {
if (qme.getSource() == null) {
// conManager.searchExpired(qme.getGUID());
/* search expired */
}
i.remove();
}
}
}
synchronized(pushRoutingTable) {
Iterator i = pushRoutingTable.values().iterator();
while (i.hasNext()) {
MessageEntry me = (MessageEntry) i.next();
if (time - me.creationTime > QUERY_HIT_LIFETIME) {
i.remove();
}
}
}
synchronized(activeSearches) {
Iterator i = activeSearches.values().iterator();
while (i.hasNext()) {
SearchEntry se = (SearchEntry) i.next();
if (time - se.creationTime > SEARCH_LIFETIME) {
i.remove();
}
}
}
}
}
public synchronized void stop()
{
if (alive) {
alive = false;
}
}
}
}
The table below shows all metrics for RoutingTable.java.




