@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.getSlices(); } String id = shardKey; int idx = shardKey.indexOf(separator); if (idx < 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)); } int m1 = mask1; int m2 = mask2; String part1 = id.substring(0, idx); int bitsSepIdx = part1.indexOf(bitsSepartor); if (bitsSepIdx > 0) { int firstBits = getBits(part1, bitsSepIdx); if (firstBits >= 0) { m1 = firstBits == 0 ? 0 : (-1 << (32 - firstBits)); m2 = firstBits == 32 ? 0 : (-1 >>> firstBits); part1 = part1.substring(0, bitsSepIdx); } } // If the upper bits are 0xF0000000, the range we want to cover is // 0xF0000000 0xFfffffff int hash1 = Hash.murmurhash3_x86_32(part1, 0, part1.length(), 0); int upperBits = hash1 & m1; int lowerBound = upperBits; int upperBound = upperBits | m2; if (m1 == 0) { // 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 completeRange = new Range(lowerBound, upperBound); List<Slice> targetSlices = new ArrayList<Slice>(1); for (Slice slice : collection.getSlices()) { Range range = slice.getRange(); if (range != null && range.overlaps(completeRange)) { targetSlices.add(slice); } } return targetSlices; }
protected final synchronized int getShardIndex(String shardId, DocCollection dc) { if (shardIndexCache == null) shardIndexCache = new HashMap<String, Integer>(20); Integer idx = shardIndexCache.get(shardId); if (idx != null) return idx.intValue(); // meh auto-boxing int s = 0; for (Slice slice : dc.getSlices()) { if (shardId.equals(slice.getName())) { shardIndexCache.put(shardId, new Integer(s)); return s; } ++s; } throw new IllegalStateException( "Cannot find index of shard '" + shardId + "' in collection: " + collection); }