Example #1
0
  @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;
  }
  @Override
  public Collection<Slice> getSearchSlicesSingle(
      String shardKey, SolrParams params, DocCollection collection) {

    if (shardKey == null) {
      return collection.getActiveSlices();
    }

    // assume the shardKey is just a slice name
    Slice slice = collection.getSlice(shardKey);
    if (slice == null) {
      throw new SolrException(
          SolrException.ErrorCode.BAD_REQUEST,
          "implicit router can't find shard "
              + shardKey
              + " in collection "
              + collection.getName());
    }

    return Collections.singleton(slice);
  }
Example #3
0
  @Override
  public int getPartition(Object o) {

    Object docId = null;
    if (o instanceof SolrInputDocument) {
      SolrInputDocument doc = (SolrInputDocument) o;
      docId = doc.getFieldValue(idField);
      if (docId == null)
        throw new IllegalArgumentException(
            "SolrInputDocument must contain a non-null value for " + idField);
    } else {
      docId = o;
    }

    if (!(docId instanceof String))
      throw new IllegalArgumentException(
          "Only String document IDs are supported by this Partitioner!");

    DocCollection dc = getDocCollection();
    Slice slice = dc.getRouter().getTargetSlice((String) docId, null, null, null, dc);
    return getShardIndex(slice.getName(), dc);
  }
Example #4
0
  protected final synchronized DocCollection getDocCollection() {
    if (docCollection == null) {
      ZkStateReader zkStateReader = getCloudSolrServer().getZkStateReader();
      docCollection = zkStateReader.getClusterState().getCollection(collection);

      // do basic checks once
      DocRouter docRouter = docCollection.getRouter();
      if (docRouter instanceof ImplicitDocRouter)
        throw new IllegalStateException(
            "Implicit document routing not supported by this Partitioner!");
      Collection<Slice> shards = getDocCollection().getSlices();
      if (shards == null || shards.size() == 0)
        throw new IllegalStateException(
            "Collection '" + collection + "' does not have any shards!");
    }
    return docCollection;
  }
Example #5
0
  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);
  }
  @Override
  public Slice getTargetSlice(
      String id,
      SolrInputDocument sdoc,
      String route,
      SolrParams params,
      DocCollection collection) {
    String shard = null;

    if (route != null) // if a route is already passed in, try to use it
    shard = route;
    else if (sdoc != null) {
      String f = getRouteField(collection);
      if (f != null) {
        Object o = sdoc.getFieldValue(f);
        if (o != null) shard = o.toString();
        else
          throw new SolrException(
              SolrException.ErrorCode.BAD_REQUEST, "No value for field " + f + " in " + sdoc);
      }
      if (shard == null) {
        Object o = sdoc.getFieldValue(_ROUTE_);
        if (o != null) {
          shard = o.toString();
        }
      }
    }

    if (shard == null) {
      shard = params.get(_ROUTE_);
    }

    if (shard != null) {

      Slice slice = collection.getSlice(shard);
      if (slice == null) {
        throw new SolrException(
            SolrException.ErrorCode.BAD_REQUEST, "No shard called =" + shard + " in " + collection);
      }
      return slice;
    }

    return null; // no shard specified... use default.
  }
Example #7
0
 public String getShardId(String docId) {
   DocCollection dc = getDocCollection();
   Slice slice = dc.getRouter().getTargetSlice(docId, null, null, null, dc);
   return slice.getName();
 }