private void removeOldMapping(RegionEntry entry, Object oldkeys) throws IMQException {

    if (oldkeys instanceof Collection) {
      for (final Object key : (Iterable) oldkeys) {
        RegionEntryToValuesMap rvMap = (RegionEntryToValuesMap) valueToEntriesMap.get(key);
        if (rvMap == null) {
          throw new IMQException(
              String.format("Indexed object's class %s compareTo function is errorneous.",
                  oldkeys.getClass().getName()));
        }
        internalIndexStats.incNumValues(-rvMap.getNumValues(entry));
        rvMap.remove(entry);
        if (rvMap.getNumEntries() == 0) {
          synchronized (rvMap) {
            // We should check for the size inside lock as some thread might
            // be adding to the same rvMap in add call.
            if (rvMap.getNumEntries() == 0) {
              if (valueToEntriesMap.remove(key, rvMap)) {
                internalIndexStats.incNumKeys(-1);
                --valueToEntriesMapSize;
              }
            }
          }
        }
      }
    } else {
      RegionEntryToValuesMap rvMap = (RegionEntryToValuesMap) valueToEntriesMap.get(oldkeys);

      // Shobhit: Fix for bug #44123
      // rvMap Can not be null if values were found in reverse map. rvMap can
      // only be null in case when "values" has wrong compareTo()
      // implementation.
      if (rvMap == null) {
        throw new IMQException(
            String.format("Indexed object's class %s compareTo function is errorneous.",
                oldkeys.getClass().getName()));
      }
      internalIndexStats.incNumValues(-rvMap.getNumValues(entry));
      rvMap.remove(entry);
      if (rvMap.getNumEntries() == 0) {
        synchronized (rvMap) {
          // We got lock first so remove will wait and check the size of
          // rvMap again before removing it.
          if (rvMap.getNumEntries() == 0) {
            if (valueToEntriesMap.remove(oldkeys, rvMap)) {
              internalIndexStats.incNumKeys(-1);
              --valueToEntriesMapSize;
            }
          }
        }
      }
    }
  }
Create an Range Index that can be used when executing queries.

@param indexName the name of this index, used for statistics collection
@param indexedExpression the expression to index on, a function dependent on region entries
       individually.
@param fromClause expression that evaluates to the collection(s) that will be queried over,
       must contain one and only one region path.
@param projectionAttributes expression that transforms each element in the result set of a
       query Return the newly created Index
geode-core/src/main/java/org/apache/geode/cache/query/internal/index/RangeIndex.java