public long getId() { int notUsed = 64 - getUsedBits(); long usedMask = (0xFFFFFFFFFFFFFFFFl << notUsed) >>> notUsed; long countMask = (0xFFFFFFFFFFFFFFFFl >>> (64 - COUNT_BITS)) << (64 - COUNT_BITS); return id & (usedMask | countMask); }
public long withoutCountBits() { return id & usedMask[getUsedBits()]; }
public boolean contains(BucketId id) { if (id.getUsedBits() < getUsedBits()) { return false; } BucketId copy = new BucketId(getUsedBits(), id.getRawId()); return (copy.getId() == getId()); }
private int getStorageSeed(BucketId bucket, ClusterState state) { int seed = ((int) bucket.getRawId()) & distributionBitMasks[state.getDistributionBitCount()]; if (bucket.getUsedBits() > 33) { int usedBits = bucket.getUsedBits() - 1; seed ^= (distributionBitMasks[usedBits - 32] & (bucket.getRawId() >> 32)) << 6; } return seed; }
public BucketId(String serialized) { if (!serialized.startsWith("BucketId(0x")) { throw new IllegalArgumentException("Serialized bucket id must start with 'BucketId(0x'"); } if (!serialized.endsWith(")")) { throw new IllegalArgumentException("Serialized bucket id must end with ')'"); } // Parse hex string after "0x" int index; char c; long id = 0; for (index = 11; index < serialized.length()-1; index++) { c = serialized.charAt(index); if (!((c>=48 && c<=57) || // digit (c>=97 && c<=102))) { // a-f throw new IllegalArgumentException("Serialized bucket id (" + serialized + ") contains illegal character at position " + index); } id <<= 4; id += Integer.parseInt(String.valueOf(c),16); } this.id = id; if (getUsedBits() == 0) { throw new IllegalArgumentException("Created bucket id "+id+", but no countbits are set"); } }
/** * @param superbucket The superbucket of which <code>progress</code> is * a sub-bucket * @param progress The sub-bucket for which a fractional progress should * be calculated * @return a value in [0, 1] specifying how far the (sub-bucket) has * reached in its superbucket. This is calculated by looking at the * bucket's split factor. */ public synchronized double progressFraction(BucketId superbucket, BucketId progress) { long revBits = bucketToKey(progress.getId()); int superUsed = superbucket.getUsedBits(); int progressUsed = progress.getUsedBits(); if (progressUsed == 0 || progressUsed < superUsed) { return 0; } int splitCount = progressUsed - superUsed; if (splitCount == 0) return 1; // Superbucket or inconsistent used-bits // Extract reversed split-bits revBits <<= superUsed; revBits >>>= 64 - splitCount; return (double)(revBits + 1) / (double)(1L << splitCount); }
private void correctTruncatedBucketCursor() { // We've truncated the bucket cursor, but in doing so we might // have moved back beyond where there are pending buckets. Consider // having a cursor value of 3 at 31 bits and then moving to 11 bits. // With 1 pending we'll normally reach a cursor of 0, even though it // should be 1 for (ProgressToken.BucketKeyWrapper bucketKey : progressToken.getBuckets().keySet()) { BucketId bid = bucketKey.toBucketId(); long idx = bucketKey.getKey() >>> (64 - bid.getUsedBits()); if (bid.getUsedBits() == distributionBitCount && idx >= progressToken.getBucketCursor()) { progressToken.setBucketCursor(idx + 1); } } if (log.isLoggable(LogLevel.SPAM)) { log.log(LogLevel.SPAM, "New range bucket cursor is " + progressToken.getBucketCursor()); } }
progressToken.updateProgress(superbucket, progress); if (superbucket.getUsedBits() != distributionBitCount) { if (!progress.equals(ProgressToken.FINISHED_BUCKET)) { log.log(LogLevel.DEBUG, "Received non-finished bucket " + superbucket + " with wrong distribution bit count (" + superbucket.getUsedBits() + "). Waiting to correct " + "until all active are done"); log.log(LogLevel.DEBUG, "Received finished bucket " + superbucket + " with wrong distribution bit count (" + superbucket.getUsedBits() + "). Waiting to correct " + "until all active are done");
int splitDistBits = bucket.getUsedBits() + 1; | (1L << bucket.getUsedBits()));
assert(entry.getValue().getState() == ProgressToken.BucketState.BUCKET_PENDING); BucketId pending = new BucketId(ProgressToken.keyToBucketId(entry.getKey().getKey())); if (pending.getUsedBits() < targetDistBits) { if (pending.getUsedBits() + 1 < targetDistBits) { maybeInconsistent = true; // Do another pass assert(entry.getValue().getState() == ProgressToken.BucketState.BUCKET_PENDING); BucketId pending = new BucketId(ProgressToken.keyToBucketId(entry.getKey().getKey())); if (pending.getUsedBits() > targetDistBits) { BucketId rightCheck = new BucketId(lastMergedBucket.getUsedBits(), lastMergedBucket.getId() | (1L << (lastMergedBucket.getUsedBits() - 1))); if (pending.equals(rightCheck)) { if (log.isLoggable(LogLevel.SPAM)) { if (pending.getUsedBits() - 1 > targetDistBits) { maybeInconsistent = true; // Do another pass
int usedBits = bucket.getUsedBits(); if (rightSibling.getProgress().getUsedBits() != 0 && log.isLoggable(LogLevel.DEBUG)) { log.log(LogLevel.DEBUG, "Bucket progress for " + rightCheck +
if (bucket.getUsedBits() < clusterState.getDistributionBitCount()) { String msg = "Cannot get ideal state for bucket " + bucket + " using " + bucket.getUsedBits() + " bits when cluster uses " + clusterState.getDistributionBitCount() + " distribution bits."; throw new TooFewBucketBitsInUseException(msg);
public int getIdealDistributorNode(ClusterState state, BucketId bucket, String upStates) throws TooFewBucketBitsInUseException, NoDistributorsAvailableException { if (bucket.getUsedBits() < state.getDistributionBitCount()) { throw new TooFewBucketBitsInUseException("Cannot get ideal state for bucket " + bucket + " using " + bucket.getUsedBits() + " bits when cluster uses " + state.getDistributionBitCount() + " distribution bits.");