/** * Refreshes all buckets whose <code>lastLookupTime</code> is too old. * @throws InterruptedException */ private void refreshOldBuckets() throws InterruptedException { long now = System.currentTimeMillis(); // refresh k-buckets for (KBucket bucket: Util.synchronizedCopy(bucketManager)) if (now > bucket.getLastLookupTime() + KademliaConstants.BUCKET_REFRESH_INTERVAL) { log.info("Refreshing k-bucket: " + bucket); refresh(bucket); } // Refresh the s-bucket by doing a lookup for a random key in each section of the bucket. // For example, if k=20 and s=100, there would be a lookup for a random key between // the 0th and the 20th sibling (i=0), another one for a random key between the 20th // and the 40th sibling (i=1), etc., and finally a lookup for a random key between the // 80th and the 100th sibling (i=4). SBucket sBucket = bucketManager.getSBucket(); BucketSection[] sections = sBucket.getSections(); for (int i=0; i<sections.length; i++) { BucketSection section = sections[i]; if (now > section.getLastLookupTime() + KademliaConstants.BUCKET_REFRESH_INTERVAL) { log.info("Refreshing s-bucket section " + i + " of " + sections.length + " (last refresh: " + new Date(section.getLastLookupTime()) + ")"); refresh(section); } } }
SBucket(Hash localDestinationHash) { super(KademliaConstants.S); distanceComparator = new PeerDistanceComparator(localDestinationHash); int numSections = (KademliaConstants.S - 1) / KademliaConstants.K + 1; if (numSections < 1) numSections = 1; sections = new BucketSection[numSections]; for (int i=0; i<numSections; i++) sections[i] = new BucketSection(BigInteger.ZERO, BigInteger.ZERO, 0); }