/** * For every bucket that hasn't been updated in this long, * or isn't close to full, * generate a random key that would be a member of that bucket. * The returned keys may be searched for to "refresh" the buckets. * @return non-null, closest first */ public List<T> getExploreKeys(long age) { List<T> rv = new ArrayList<T>(_buckets.size()); long old = _context.clock().now() - age; getReadLock(); try { for (KBucket<T> b : _buckets) { int curSize = b.getKeyCount(); // Always explore the closest bucket if ((b.getRangeBegin() == 0) || (b.getLastChanged() < old || curSize < BUCKET_SIZE * 3 / 4)) rv.add(generateRandomKey(b)); } } finally { releaseReadLock(); } return rv; }
/** @since 0.9.10 */ public void testGenRandom() { int errors = 0; for (KBucket<Hash> b : set.getBuckets()) { for (int j = 0; j < 4000; j++) { Hash rand = set.generateRandomKey(b); int range = set.getRange(rand); if (range < b.getRangeBegin() || range > b.getRangeEnd()) { log.error("Generate random key failed range=" + range + " for " + rand + " meant for bucket " + b); errors++; } } } assertTrue(errors == 0); }