protected static List<ByteArrayRange> getQueryRanges(
      final BinnedNumericDataset[] binnedQueries,
      final SpaceFillingCurve sfc,
      final int maxRanges,
      final byte tier) {
    final List<ByteArrayRange> queryRanges = new ArrayList<ByteArrayRange>();

    int maxRangeDecompositionPerBin = maxRanges;
    if ((maxRanges > 1) && (binnedQueries.length > 1)) {
      maxRangeDecompositionPerBin =
          (int) Math.ceil((double) maxRanges / (double) binnedQueries.length);
    }
    for (final BinnedNumericDataset binnedQuery : binnedQueries) {
      final RangeDecomposition rangeDecomp =
          sfc.decomposeRange(binnedQuery, true, maxRangeDecompositionPerBin);
      final byte[] tierAndBinId =
          ByteArrayUtils.combineArrays(
              new byte[] {tier
                // we're assuming tiers only go to 127 (the max byte
                // value)
              },
              binnedQuery.getBinId());
      for (final ByteArrayRange range : rangeDecomp.getRanges()) {
        queryRanges.add(
            new ByteArrayRange(
                new ByteArrayId(
                    ByteArrayUtils.combineArrays(tierAndBinId, range.getStart().getBytes())),
                new ByteArrayId(
                    ByteArrayUtils.combineArrays(tierAndBinId, range.getEnd().getBytes()))));
      }
    }
    return queryRanges;
  }
 protected static List<ByteArrayId> decomposeRangesForEntry(
     final BinnedNumericDataset index, final byte tierId, final SpaceFillingCurve sfc) {
   final List<ByteArrayId> retVal = new ArrayList<ByteArrayId>();
   final byte[] tierAndBinId = ByteArrayUtils.combineArrays(new byte[] {tierId}, index.getBinId());
   final RangeDecomposition rangeDecomp = sfc.decomposeRange(index, false, DEFAULT_MAX_RANGES);
   // this range does not fit into a single row ID at the lowest
   // tier, decompose it
   for (final ByteArrayRange range : rangeDecomp.getRanges()) {
     final byte[] currentRowId =
         Arrays.copyOf(range.getStart().getBytes(), range.getStart().getBytes().length);
     retVal.add(new ByteArrayId(ByteArrayUtils.combineArrays(tierAndBinId, currentRowId)));
     while (!Arrays.equals(currentRowId, range.getEnd().getBytes())) {
       // increment until we reach the end row ID
       boolean overflow = !ByteArrayUtils.increment(currentRowId);
       if (!overflow) {
         retVal.add(new ByteArrayId(ByteArrayUtils.combineArrays(tierAndBinId, currentRowId)));
       } else {
         // the increment caused an overflow which shouldn't
         // ever happen assuming the start row ID is less
         // than the end row ID
         LOGGER.warn(
             "Row IDs overflowed when ingesting data; start of range decomposition must be less than or equal to end of range. This may be because the start of the decomposed range is higher than the end of the range.");
         overflow = true;
         break;
       }
     }
   }
   return retVal;
 }
 private static final void setParameter(
     final Configuration config,
     final Class<?> scope,
     final Object val,
     final ParameterEnum configItem) {
   if (val != null) {
     if (val instanceof Long) {
       config.setLong(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()), ((Long) val));
     } else if (val instanceof Double) {
       config.setDouble(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()), ((Double) val));
     } else if (val instanceof Boolean) {
       config.setBoolean(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()), ((Boolean) val));
     } else if (val instanceof Integer) {
       config.setInt(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()), ((Integer) val));
     } else if (val instanceof Class) {
       config.setClass(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()),
           ((Class) val),
           ((Class) val));
     } else if (val instanceof byte[]) {
       config.set(
           GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()),
           ByteArrayUtils.byteArrayToString((byte[]) val));
     } else {
       config.set(GeoWaveConfiguratorBase.enumToConfKey(scope, configItem.self()), val.toString());
     }
   }
 }
 protected static List<ByteArrayId> getRowIdsAtTier(
     final BinnedNumericDataset index,
     final byte tierId,
     final SpaceFillingCurve sfc,
     final BigInteger maxEstimatedDuplicateIds,
     final int sfcIndex) {
   final List<ByteArrayId> retVal = new ArrayList<ByteArrayId>();
   final BigInteger rowCount = sfc.getEstimatedIdCount(index);
   if (rowCount.equals(BigInteger.ONE)) {
     final byte[] tierAndBinId =
         ByteArrayUtils.combineArrays(new byte[] {tierId}, index.getBinId());
     final double[] maxValues = index.getMaxValuesPerDimension();
     retVal.add(new ByteArrayId(ByteArrayUtils.combineArrays(tierAndBinId, sfc.getId(maxValues))));
     return retVal;
   } else if ((maxEstimatedDuplicateIds == null)
       || (rowCount.compareTo(maxEstimatedDuplicateIds) <= 0)
       || (sfcIndex == 0)) {
     return decomposeRangesForEntry(index, tierId, sfc);
   }
   return null;
 }
 @Override
 public void init(
     final SortedKeyValueIterator<Key, Value> source,
     final Map<String, String> options,
     final IteratorEnvironment env)
     throws IOException {
   this.source = source;
   if (options == null) {
     throw new IllegalArgumentException(
         "Arguments must be set for " + NumericIndexStrategyFilterIterator.class.getName());
   }
   try {
     if (options.containsKey(INDEX_STRATEGY_KEY)) {
       final String idxStrategyStr = options.get(INDEX_STRATEGY_KEY);
       final byte[] idxStrategyBytes = ByteArrayUtils.byteArrayFromString(idxStrategyStr);
       indexStrategy = PersistenceUtils.fromBinary(idxStrategyBytes, NumericIndexStrategy.class);
     } else {
       throw new IllegalArgumentException(
           "'"
               + INDEX_STRATEGY_KEY
               + "' must be set for "
               + NumericIndexStrategyFilterIterator.class.getName());
     }
     if (options.containsKey(COORDINATE_RANGE_KEY)) {
       final String coordRangeStr = options.get(COORDINATE_RANGE_KEY);
       final byte[] coordRangeBytes = ByteArrayUtils.byteArrayFromString(coordRangeStr);
       final ArrayOfArrays arrays = new ArrayOfArrays();
       arrays.fromBinary(coordRangeBytes);
       rangeCache = RangeLookupFactory.createMultiRangeLookup(arrays.getCoordinateArrays());
     } else {
       throw new IllegalArgumentException(
           "'"
               + COORDINATE_RANGE_KEY
               + "' must be set for "
               + NumericIndexStrategyFilterIterator.class.getName());
     }
   } catch (final Exception e) {
     throw new IllegalArgumentException(e);
   }
 }