i2p源码笔记--Trimmer.java

注:本章笔记中将包含一下文件:KBucketTrimmer.java RandomIfOldTrimmer.java TandomTrimmer.java RejectTrimmer.java SelectionCollection.java XORComparator.java等六个文件

文章目录

  • KBucketTrimmer
  • RandomTrimmer
  • RandomIfOldTrimmer.java
  • RejectTrimmer
  • XORComparator

KBucketTrimmer

这是一个范型接口interface,我们知道当一个bucket 很大的时候就需要split,但是split是有数量和次数限制的,当上述情况同时发生的时候我们就需要调用trimmer相关的来进行修正,具体怎么修正继续看其他文件,这里只是定义类一个interface,接口中只有一个函数,返回值为bool类型,看主食应该是如果节点插入进入到buckety汇总那么就返回true,而如果没有返回false。接受两个参数,一个是接受KBucket< K >d的,另一个接受K类型的用来表示要添加的节点

package net.i2p.kademlia;

import net.i2p.data.SimpleDataStructure;

/**
 *  Called when a kbucket can no longer be split and is too big
 *  @since 0.9.2 in i2psnark, moved to core in 0.9.10
 */
public interface KBucketTrimmer<K extends SimpleDataStructure> {
    /**
     *  Called from add() just before adding the entry.
     *  You may call getEntries() and/or remove() from here.
     *  Do NOT call add().
     *  To always discard a newer entry, always return false.
     *
     *  @param kbucket the kbucket that is now too big
     *  @return true to actually add the entry.
     */
    public boolean trim(KBucket<K> kbucket, K toAdd);
}

RandomTrimmer

这是一个范型类,实现了KBucketTrimmer这个interface,。在函数trim中,如果要添加的的bucket的size仍旧小于最大值,那么就可以继续添加,返回true,而如果size 大于或者等于最大值,那么就需要随机移除一个,使用i2pappcontext中的random.nextint来获取随机的,然后使用kbucket.remove函数来移除,然后返回true
i2pappcontext已经多次出现了,下一个文件用来记录这个文件的笔记

package net.i2p.kademlia;

import java.util.ArrayList;
import java.util.List;

import net.i2p.I2PAppContext;
import net.i2p.data.SimpleDataStructure;

/**
 *  Removes a random element. Not resistant to flooding.
 *  @since 0.9.2 in i2psnark, moved to core in 0.9.10
 */
public class RandomTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
    protected final I2PAppContext _ctx;
    private final int _max;

    public RandomTrimmer(I2PAppContext ctx, int max) {
        _ctx = ctx;
        _max = max;
    }

    public boolean trim(KBucket<T> kbucket, T toAdd) {
        List<T> e = new ArrayList<T>(kbucket.getEntries());
        int sz = e.size();
        // concurrency
        if (sz < _max)
            return true;
        T toRemove = e.get(_ctx.random().nextInt(sz));
        kbucket.remove(toRemove);
        return true;
    }
}

RandomIfOldTrimmer.java

这个函数继承了RandomTrimmer,功能一样,也是随机移除一个key,但是发生的条件是如果一个bucket在五分钟之内没有更新或者说没有任何改动的情况下,就需要调用这个函数来随机remove一个key,构造函数调用父类,

package net.i2p.kademlia;

import net.i2p.I2PAppContext;
import net.i2p.data.SimpleDataStructure;

/**
*  Removes a random element, but only if the bucket hasn't changed in 5 minutes.
*  @since 0.9.2 in i2psnark, moved to core in 0.9.10
*/
public class RandomIfOldTrimmer<T extends SimpleDataStructure> extends RandomTrimmer<T> {

   public RandomIfOldTrimmer(I2PAppContext ctx, int max) {
       super(ctx, max);
   }

   public boolean trim(KBucket<T> kbucket, T toAdd) {
       if (kbucket.getLastChanged() > _ctx.clock().now() - 5*60*1000)
           return false;
       return super.trim(kbucket, toAdd);
   }
}

RejectTrimmer

package net.i2p.kademlia;

import net.i2p.data.SimpleDataStructure;

/**
 *  Removes nothing and always rejects the add. Flood resistant..
 *  @since 0.9.2 in i2psnark, moved to core in 0.9.10
 */
public class RejectTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
    public boolean trim(KBucket<T> kbucket, T toAdd) {
        return false;
    }
}

XORComparator

使用xor异或距离来对base key的hash进行排序。

package net.i2p.kademlia;

import java.io.Serializable;
import java.util.Comparator;

import net.i2p.data.SimpleDataStructure;

/**
 * Help sort Hashes in relation to a base key using the XOR metric
 *
 * @since 0.9.2 in i2psnark, moved to core in 0.9.10
 */
public class XORComparator<T extends SimpleDataStructure> implements Comparator<T>, Serializable {
    private final byte[] _base;

    /**
     * @param target key to compare distances with
     */
    public XORComparator(T target) {
        _base = target.getData();
    }

    public int compare(T lhs, T rhs) {
        // same as the following but byte-by-byte for efficiency
        //byte lhsDelta[] = DataHelper.xor(lhs.getData(), _base);
        //byte rhsDelta[] = DataHelper.xor(rhs.getData(), _base);
        //return DataHelper.compareTo(lhsDelta, rhsDelta);
        byte lhsb[] = lhs.getData();
        byte rhsb[] = rhs.getData();
        for (int i = 0; i < _base.length; i++) {
            int ld = (lhsb[i] ^ _base[i]) & 0xff;
            int rd = (rhsb[i] ^ _base[i]) & 0xff;
            if (ld < rd)
                return -1;
            if (ld > rd)
                return 1;
        }
        return 0;
    }
}

首先创建一个字节数组 byte[] _base来,该类继承SimpleDataStructure 实现Comparator< T >,和Serializable。

  • 构造函数 获取tartget(T 类型),获取他的hash序列
  • compare函数 接受两个节点,两个节点首先获取hash的字节序列,然后和构造函数中的那个节点进行异或看那个节点的距离更小。为了使异或的过程速度更快,就需要直接进行位操作,而不是用函数(datahelper.xor)来进行异或

到现在kademlia就将所有的 文件的源代码的笔记写完了,之后或许会考虑i2pappcontext 以及从顶上下来看代码

你可能感兴趣的:(i2p)