public int compare(KBucket<T> l, KBucket<T> r) { if (l.getRangeEnd() < r.getRangeBegin()) return -1; if (l.getRangeBegin() > r.getRangeEnd()) return 1; return 0; } }
/** * No lock required. * FIXME will split the closest buckets too far if B > 1 and K < 2**B * Won't ever really happen and if it does it still works. */ private boolean shouldSplit(KBucket<T> b) { return b.getRangeBegin() != b.getRangeEnd() && b.getKeyCount() > BUCKET_SIZE; }
/** * The bucket number that contains this range number * Caller must hold read lock or write lock * @return 0 to max-1 or -1 for us */ private int pickBucket(int range) { // If B is small, a linear search from back to front // is most efficient since most of the keys are at the end... // If B is larger, there's a lot of sub-buckets // of equal size to be checked so a binary search is better if (B_VALUE <= 3) { for (int i = _buckets.size() - 1; i >= 0; i--) { KBucket<T> b = _buckets.get(i); if (range >= b.getRangeBegin() && range <= b.getRangeEnd()) return i; } return -1; } else { KBucket<T> dummy = new DummyBucket<T>(range); return Collections.binarySearch(_buckets, dummy, new BucketComparator<T>()); } }
int end = bucket.getRangeEnd();
e2 = b0.getRangeEnd(); if (B_VALUE == 1 || ((s1 & (B_FACTOR - 1)) == 0 &&
/** @since 0.9.10 */ public void testOrder() { int bits = Hash.HASH_LENGTH * 8; int errors = 0; int lastEnd = -1; for (KBucket<Hash> b : set.getBuckets()) { int beg = b.getRangeBegin(); if (beg != lastEnd + 1) { log.error("Out of order: " + b); errors++; } lastEnd = b.getRangeEnd(); } if (lastEnd != (bits * (1 << (B-1))) - 1) { log.error("Out of order: last=" + lastEnd); errors++; } assertTrue(errors == 0); }
/** @since 0.9.10 */ public void testAudit() { int errors = 0; for (KBucket<Hash> b : set.getBuckets()) { for (Hash sds : b.getEntries()) { int range = set.getRange(sds); if (range < b.getRangeBegin() || range > b.getRangeEnd()) { log.error("Hash " + sds + " with range " + range + " does not belong in " + b); errors++; } } } assertTrue(errors == 0); }
/** @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); }