⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhtrouterimpl.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	findContact(
		byte[]		node_id )
	{
		Object[]	res = findContactSupport( node_id );
				
		return((DHTRouterContact)res[1]);
	}
	
	protected DHTRouterNodeImpl
	findNode(
		byte[]	node_id )
	{
		Object[]	res = findContactSupport( node_id );
				
		return((DHTRouterNodeImpl)res[0]);	
	}
	
	protected Object[]
	findContactSupport(
		byte[]		node_id )
	{
		try{
			this_mon.enter();
		
			DHTRouterNodeImpl	current_node	= root;
			
			for (int i=0;i<node_id.length;i++){
				
				if ( current_node.getBuckets() != null ){
				
					break;
				}
	
				byte	b = node_id[i];
				
				int	j = 7;
				
				while( j >= 0 ){
						
					boolean	bit = ((b>>j)&0x01)==1?true:false;
					
					if ( current_node.getBuckets() != null ){
						
						break;
					}
									
					if ( bit ){
						
						current_node = current_node.getLeft();
						
					}else{
						
						current_node = current_node.getRight();
					}
					
					j--;
				}
			}
			
			List	buckets = current_node.getBuckets();
			
			for (int k=0;k<buckets.size();k++){
				
				DHTRouterContactImpl	contact = (DHTRouterContactImpl)buckets.get(k);
				
				if ( Arrays.equals(node_id, contact.getID())){
	
					return( new Object[]{ current_node, contact });
				}
			}
			
			return( new Object[]{ current_node, null });
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	protected long
	getNodeCount()
	{
		return( getNodeCount( root ));
	}
	
	protected long
	getNodeCount(
		DHTRouterNodeImpl	node )
	{
		if ( node.getBuckets() != null ){
			
			return( 1 );
			
		}else{
			
			return( 1 + getNodeCount( node.getLeft())) + getNodeCount( node.getRight());
		}
	}
	
	protected long
	getContactCount()
	{
		return( getContactCount( root ));
	}
	
	protected long
	getContactCount(
		DHTRouterNodeImpl	node )
	{
		if ( node.getBuckets() != null ){
			
			return( node.getBuckets().size());
			
		}else{
			
			return( getContactCount( node.getLeft())) + getContactCount( node.getRight());
		}
	}
	
	public List
	findBestContacts(
		int		max )
	{
		Set	set = 
			new TreeSet(
					new Comparator()
					{
						public int
						compare(
							Object	o1,
							Object	o2 )
						{
							DHTRouterContactImpl	c1 = (DHTRouterContactImpl)o1;
							DHTRouterContactImpl	c2 = (DHTRouterContactImpl)o2;
							
							return((int)( c2.getTimeAlive() - c1.getTimeAlive()));
						}
					});
		
		
		try{
			this_mon.enter();

			findAllContacts( set, root );
			
		}finally{
			
			this_mon.exit();
		}
		
		List	result = new ArrayList( max );
	
		Iterator	it = set.iterator();
		
		while( it.hasNext() && (max <= 0 || result.size() < max )){
			
			result.add( it.next());
		}
		
		return( result );
	}
	
	public List
	getAllContacts()
	{
		try{
			this_mon.enter();

			List	l = new ArrayList();
			
			findAllContacts( l, root );
			
			return( l );
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	protected void
	findAllContacts(
		Set					set,
		DHTRouterNodeImpl	node )
	{
		List	buckets = node.getBuckets();
		
		if ( buckets == null ){
			
			findAllContacts( set, node.getLeft());
			
			findAllContacts( set, node.getRight());
		}else{
			
			for (int i=0;i<buckets.size();i++){
				
				DHTRouterContactImpl	contact = (DHTRouterContactImpl)buckets.get(i);
								
				set.add( contact );
			}
		}
	}
	
	protected void
	findAllContacts(
		List				list,
		DHTRouterNodeImpl	node )
	{
		List	buckets = node.getBuckets();
		
		if ( buckets == null ){
			
			findAllContacts( list, node.getLeft());
			
			findAllContacts( list, node.getRight());
		}else{
			
			for (int i=0;i<buckets.size();i++){
				
				DHTRouterContactImpl	contact = (DHTRouterContactImpl)buckets.get(i);
								
				list.add( contact );
			}
		}
	}
	
	public void
	seed()
	{
			// refresh all buckets apart from closest neighbour
		
		byte[]	path = new byte[router_node_id.length];
		
		List	ids = new ArrayList();
		
		try{
			this_mon.enter();
			
			refreshNodes( ids, root, path, true, 0 );
			
		}finally{
			
			this_mon.exit();
		}
		
		for (int i=0;i<ids.size();i++){
			
			requestLookup((byte[])ids.get(i), "Seeding DHT" );
		}
	}
	
	protected void
	refreshNodes(
		List				nodes_to_refresh,
		DHTRouterNodeImpl	node,
		byte[]				path,
		boolean				seeding,
		long				max_permitted_idle )	// 0 -> don't check
	{
			// when seeding we don't do the smallest subtree
		
		if ( seeding && node == smallest_subtree ){
			
			return;
		}
		
		if ( max_permitted_idle != 0 ){
			
			if ( node.getTimeSinceLastLookup() <= max_permitted_idle ){
				
				return;
			}
		}
		
		if ( node.getBuckets() != null ){
		
				// and we also don't refresh the bucket containing the router id when seeding
			
			if ( seeding && node.containsRouterNodeID()){
				
				return;
			}
			
			refreshNode( nodes_to_refresh, node, path );		
		}
		
			// synchronous refresh may result in this bucket being split
			// so we retest here to refresh sub-buckets as required
		
		if ( node.getBuckets() == null ){
			
			int	depth = node.getDepth();
			
			byte	mask = (byte)( 0x01<<(7-(depth%8)));
			
			path[depth/8] = (byte)( path[depth/8] | mask );
			
			refreshNodes( nodes_to_refresh, node.getLeft(), path,seeding, max_permitted_idle  );
			
			path[depth/8] = (byte)( path[depth/8] & ~mask );
		
			refreshNodes( nodes_to_refresh, node.getRight(), path,seeding, max_permitted_idle  );
		}
	}
	
	protected void
	refreshNode(
		List				nodes_to_refresh,
		DHTRouterNodeImpl	node,
		byte[]				path )
	{
			// pick a random id in the node's range.
		
		byte[]	id = new byte[router_node_id.length];
		
		random.nextBytes( id );
		
		int	depth = node.getDepth();
		
		for (int i=0;i<depth;i++){
			
			byte	mask = (byte)( 0x01<<(7-(i%8)));
			
			boolean bit = ((path[i/8]>>(7-(i%8)))&0x01 ) == 1;

			if ( bit ){
				
				id[i/8] = (byte)( id[i/8] | mask );

			}else{
				
				id[i/8] = (byte)( id[i/8] & ~mask );	
			}
		}
		
		nodes_to_refresh.add( id );
	}
	
	protected DHTRouterNodeImpl
	getSmallestSubtree()
	{
		return( smallest_subtree );
	}
	
	public void
	recordLookup(
		byte[]	node_id )
	{
		findNode( node_id ).setLastLookupTime();
	}
	
	public void
	refreshIdleLeaves(
		long	idle_max)
	{
		// while we are synchronously refreshing the smallest subtree the tree can mutate underneath us
		// as new contacts are discovered. We NEVER merge things back together
		
		byte[]	path = new byte[router_node_id.length];
		
		List	ids = new ArrayList();
		
		try{
			this_mon.enter();
			
			refreshNodes( ids, root, path, false, idle_max );
			
		}finally{
			
			this_mon.exit();
		}
		
		for (int i=0;i<ids.size();i++){
			
			requestLookup((byte[])ids.get(i), "Idle leaf refresh" );
		}
	}
	
	public boolean
	requestPing(
		byte[]		node_id )
	{
		Object[] res = findContactSupport( node_id );
	
		DHTRouterContactImpl	contact = (DHTRouterContactImpl)res[1];
		
		if ( contact != null ){
			
			adapter.requestPing( contact );
			
			return( true );
		}
		
		return( false );
	}
	
	protected void
	requestPing(
		DHTRouterContactImpl	contact )
	{
			// make sure we don't do the ping when synchronised
		
		DHTLog.log( "DHTRouter: requestPing:" + DHTLog.getString( contact.getID()));
		
		if ( contact == local_contact ){
			
			Debug.out( "pinging local contact" );
		}
		
		try{
			this_mon.enter();
			
			if ( !outstanding_pings.contains( contact )){
			
				outstanding_pings.add( contact );
			}
		}finally{
			
			this_mon.exit();
		}
	}
	
	protected void
	dispatchPings()
	{
		if ( outstanding_pings.size() == 0 ){
			
			return;
		}
		
		List	pings;
		
		try{
			this_mon.enter();
		
			pings	= outstanding_pings;
			
			outstanding_pings = new ArrayList();
			
		}finally{
			
			this_mon.exit();
		}
		
		for (int i=0;i<pings.size();i++){
			
			adapter.requestPing((DHTRouterContactImpl)pings.get(i));
		}
	}
	
	protected void
	requestNodeAdd(
		DHTRouterContactImpl	contact )
	{
			// make sure we don't do the addition when synchronised
		
		DHTLog.log( "DHTRouter: requestNodeAdd:" + DHTLog.getString( contact.getID()));
		
		if ( contact == local_contact ){

			Debug.out( "adding local contact" );
		}
		
		try{
			this_mon.enter();
			
			if ( !outstanding_adds.contains( contact )){
			
				outstanding_adds.add( contact );
			}
		}finally{
			
			this_mon.exit();
		}
	}
	
	protected void
	dispatchNodeAdds()
	{
		if ( outstanding_adds.size() == 0 ){
			
			return;
		}
		
		List	adds;
		
		try{
			this_mon.enter();
		
			adds	= outstanding_adds;
			
			outstanding_adds = new ArrayList();
			
		}finally{
			
			this_mon.exit();
		}
		
		for (int i=0;i<adds.size();i++){
			
			adapter.requestAdd((DHTRouterContactImpl)adds.get(i));
		}
	}

	public byte[]
	refreshRandom()
	{
		byte[]	id = new byte[router_node_id.length];
		
		random.nextBytes( id );
	
		requestLookup( id, "Random Refresh" );
		
		return( id );
	}
	
	protected void
	requestLookup(
		byte[]		id,
		String		description )
	{
		DHTLog.log( "DHTRouter: requestLookup:" + DHTLog.getString( id ));
		
		adapter.requestLookup( id, description );
	}
	
	protected void
	getStatsSupport(
		long[]				stats_array,
		DHTRouterNodeImpl	node )
	{
		stats_array[DHTRouterStats.ST_NODES]++;
		
		List	buckets = node.getBuckets();
		
		if ( buckets == null ){
			
			getStatsSupport( stats_array, node.getLeft());
			
			getStatsSupport( stats_array, node.getRight());
			
		}else{
			
			stats_array[DHTRouterStats.ST_LEAVES]++;
			
			stats_array[DHTRouterStats.ST_CONTACTS] += buckets.size();
			
			for (int i=0;i<buckets.size();i++){
				
				DHTRouterContactImpl	contact = (DHTRouterContactImpl)buckets.get(i);
				
				if ( contact.getFirstFailTime() > 0 ){
					
					stats_array[DHTRouterStats.ST_CONTACTS_DEAD]++;
					
				}else if ( contact.hasBeenAlive()){
					
					stats_array[DHTRouterStats.ST_CONTACTS_LIVE]++;
					
				}else{
					
					stats_array[DHTRouterStats.ST_CONTACTS_UNKNOWN]++;
				}
			}
			
			List	rep = node.getReplacements();
			
			if ( rep != null ){
				
				stats_array[DHTRouterStats.ST_REPLACEMENTS] += rep.size();
			}
		}
	}
	
	protected long[]
	getStatsSupport()
	{
		 /* number of nodes
		 * number of leaves
		 * number of contacts
		 * number of replacements
		 * number of live contacts
		 * number of unknown contacts
		 * number of dying contacts
		 */
		
		try{
			this_mon.enter();
		
			long[]	res = new long[7];
		
			getStatsSupport( res, root );
		
			return( res );
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	protected void
	log(
		String	str )
	{
		logger.log( str );
	}
	
	public void
	print()
	{
		try{
			this_mon.enter();
		
			log( "DHT: " + DHTLog.getString2(router_node_id) + ", node count = " + getNodeCount()+ ", contacts =" + getContactCount());
		
			root.print( "", "" );
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	public void
	destroy()
	{
		notifyDead();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -