end = max; ranges.add(new Range((int) start, (int) end)); start = end + 1L; targetStart = targetEnd + 1L;
public List<Range> partitionRangeByKey(String key, Range range) { List<Range> result = new ArrayList<>(3); Range keyRange = keyHashRange(key); if (!keyRange.overlaps(range)) { throw new IllegalArgumentException("Key range does not overlap given range"); } if (keyRange.equals(range)) { return Collections.singletonList(keyRange); } else if (keyRange.isSubsetOf(range)) { result.add(new Range(range.min, keyRange.min - 1)); result.add(keyRange); result.add((new Range(keyRange.max + 1, range.max))); } else if (range.includes(keyRange.max)) { result.add(new Range(range.min, keyRange.max)); result.add(new Range(keyRange.max + 1, range.max)); } else { result.add(new Range(range.min, keyRange.min - 1)); result.add(new Range(keyRange.min, range.max)); } return result; }
end = max; ranges.add(new Range((int) start, (int) end)); start = end + 1L; targetStart = targetEnd + 1L;
@Override public Collection<Slice> getSearchSlicesSingle(String shardKey, SolrParams params, DocCollection collection) { if (shardKey == null) { // search across whole collection // TODO: this may need modification in the future when shard splitting could cause an overlap return collection.getActiveSlices(); } String id = shardKey; if (shardKey.indexOf(SEPARATOR) < 0) { // shardKey is a simple id, so don't do a range return Collections.singletonList(hashToSlice(Hash.murmurhash3_x86_32(id, 0, id.length(), 0), collection)); } Range completeRange = new KeyParser(id).getRange(); List<Slice> targetSlices = new ArrayList<>(1); for (Slice slice : collection.getActiveSlices()) { Range range = slice.getRange(); if (range != null && range.overlaps(completeRange)) { targetSlices.add(slice); } } return targetSlices; }
/** * Returns the range for each partition */ public List<Range> partitionRange(int partitions, Range range) { int min = range.min; int max = range.max; assert max >= min; if (partitions == 0) return Collections.EMPTY_LIST; long rangeSize = (long)max - (long)min; long rangeStep = Math.max(1, rangeSize / partitions); List<Range> ranges = new ArrayList<>(partitions); long start = min; long end = start; while (end < max) { end = start + rangeStep; // make last range always end exactly on MAX_VALUE if (ranges.size() == partitions - 1) { end = max; } ranges.add(new Range((int)start, (int)end)); start = end + 1L; } return ranges; }
Range getRange() { int lowerBound; int upperBound; if (triLevel) { lowerBound = hashes[0] & masks[0] | hashes[1] & masks[1]; upperBound = lowerBound | masks[2]; } else { lowerBound = hashes[0] & masks[0]; upperBound = lowerBound | masks[1]; } // If the upper bits are 0xF0000000, the range we want to cover is // 0xF0000000 0xFfffffff if ((masks[0] == 0 && !triLevel) || (masks[0] == 0 && masks[1] == 0 && triLevel)) { // no bits used from first part of key.. the code above will produce 0x000000000->0xffffffff // which only works on unsigned space, but we're using signed space. lowerBound = Integer.MIN_VALUE; upperBound = Integer.MAX_VALUE; } Range r = new Range(lowerBound, upperBound); return r; }
/** * Returns the range for each partition */ public List<Range> partitionRange(int partitions, Range range) { int min = range.min; int max = range.max; assert max >= min; if (partitions == 0) return Collections.EMPTY_LIST; long rangeSize = (long)max - (long)min; long rangeStep = Math.max(1, rangeSize / partitions); List<Range> ranges = new ArrayList<>(partitions); long start = min; long end = start; while (end < max) { end = start + rangeStep; // make last range always end exactly on MAX_VALUE if (ranges.size() == partitions - 1) { end = max; } ranges.add(new Range((int)start, (int)end)); start = end + 1L; } return ranges; }
@Override public Collection<Slice> getSearchSlicesSingle(String shardKey, SolrParams params, DocCollection collection) { if (shardKey == null) { // search across whole collection // TODO: this may need modification in the future when shard splitting could cause an overlap return collection.getActiveSlices(); } String id = shardKey; if (shardKey.indexOf(SEPARATOR) < 0) { // shardKey is a simple id, so don't do a range return Collections.singletonList(hashToSlice(Hash.murmurhash3_x86_32(id, 0, id.length(), 0), collection)); } Range completeRange = new KeyParser(id).getRange(); List<Slice> targetSlices = new ArrayList<>(1); for (Slice slice : collection.getActiveSlicesArr()) { Range range = slice.getRange(); if (range != null && range.overlaps(completeRange)) { targetSlices.add(slice); } } return targetSlices; }
public List<Range> partitionRangeByKey(String key, Range range) { List<Range> result = new ArrayList<>(3); Range keyRange = keyHashRange(key); if (!keyRange.overlaps(range)) { throw new IllegalArgumentException("Key range does not overlap given range"); } if (keyRange.equals(range)) { return Collections.singletonList(keyRange); } else if (keyRange.isSubsetOf(range)) { result.add(new Range(range.min, keyRange.min - 1)); result.add(keyRange); result.add((new Range(keyRange.max + 1, range.max))); } else if (range.includes(keyRange.max)) { result.add(new Range(range.min, keyRange.max)); result.add(new Range(keyRange.max + 1, range.max)); } else { result.add(new Range(range.min, keyRange.min - 1)); result.add(new Range(keyRange.min, range.max)); } return result; }
Range getRange() { int lowerBound; int upperBound; if (triLevel) { lowerBound = hashes[0] & masks[0] | hashes[1] & masks[1]; upperBound = lowerBound | masks[2]; } else { lowerBound = hashes[0] & masks[0]; upperBound = lowerBound | masks[1]; } // If the upper bits are 0xF0000000, the range we want to cover is // 0xF0000000 0xFfffffff if ((masks[0] == 0 && !triLevel) || (masks[0] == 0 && masks[1] == 0 && triLevel)) { // no bits used from first part of key.. the code above will produce 0x000000000->0xffffffff // which only works on unsigned space, but we're using signed space. lowerBound = Integer.MIN_VALUE; upperBound = Integer.MAX_VALUE; } Range r = new Range(lowerBound, upperBound); return r; }
public Range fullRange() { return new Range(Integer.MIN_VALUE, Integer.MAX_VALUE); }
@Override public void write(JSONWriter writer) { writer.write(toString()); }
public Range fullRange() { return new Range(Integer.MIN_VALUE, Integer.MAX_VALUE); }
public Range fromString(String range) { int middle = range.indexOf('-'); String minS = range.substring(0, middle); String maxS = range.substring(middle+1); long min = Long.parseLong(minS, 16); // use long to prevent the parsing routines from potentially worrying about overflow long max = Long.parseLong(maxS, 16); return new Range((int)min, (int)max); }
protected Slice hashToSlice(int hash, DocCollection collection) { for (Slice slice : collection.getActiveSlices()) { Range range = slice.getRange(); if (range != null && range.includes(hash)) return slice; } throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No active slice servicing hash code " + Integer.toHexString(hash) + " in " + collection); }
/** * Get Range for a given CompositeId based route key * * @param routeKey to return Range for * @return Range for given routeKey */ public Range keyHashRange(String routeKey) { if (routeKey.indexOf(SEPARATOR) < 0) { int hash = sliceHash(routeKey, null, null, null); return new Range(hash, hash); } return new KeyParser(routeKey).getRange(); }
public boolean overlaps(Range other) { return includes(other.min) || includes(other.max) || isSubsetOf(other); }
/** * Get Range for a given CompositeId based route key * * @param routeKey to return Range for * @return Range for given routeKey */ public Range keyHashRange(String routeKey) { if (routeKey.indexOf(SEPARATOR) < 0) { int hash = sliceHash(routeKey, null, null, null); return new Range(hash, hash); } return new KeyParser(routeKey).getRange(); }
public Range fromString(String range) { int middle = range.indexOf('-'); String minS = range.substring(0, middle); String maxS = range.substring(middle+1); long min = Long.parseLong(minS, 16); // use long to prevent the parsing routines from potentially worrying about overflow long max = Long.parseLong(maxS, 16); return new Range((int)min, (int)max); }
protected Slice hashToSlice(int hash, DocCollection collection) { final Slice[] slices = collection.getActiveSlicesArr(); for (Slice slice : slices) { Range range = slice.getRange(); if (range != null && range.includes(hash)) return slice; } throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No active slice servicing hash code " + Integer.toHexString(hash) + " in " + collection); }