private boolean basicRemoveMapping(Object key, RegionEntry entry, boolean findOldKey)
      throws IMQException {
    boolean found = false;
    boolean possiblyAlreadyRemoved = false;
    try {
      Object newKey = convertToIndexKey(key, entry);
      if (DefaultQuery.testHook != null) {
        DefaultQuery.testHook.doTestHook(DefaultQuery.TestHook.SPOTS.ATTEMPT_REMOVE, null, null);
      }
      boolean retry = false;
      do {
        retry = false;
        Object regionEntries = valueToEntriesMap.get(newKey);
        if (regionEntries == TRANSITIONING_TOKEN) {
          if (DefaultQuery.testHook != null) {
            DefaultQuery.testHook.doTestHook(DefaultQuery.TestHook.SPOTS.ATTEMPT_RETRY, null, null);
          }
          retry = true;
          continue;
        } else if (regionEntries != null) {
          if (regionEntries instanceof RegionEntry) {
            found = regionEntries == entry;
            if (found) {
              if (valueToEntriesMap.remove(newKey, regionEntries)) {
                if (newKey != IndexManager.NULL && newKey != QueryService.UNDEFINED) {
                  internalIndexStats.incNumKeys(-1);
                }
                numIndexKeys.decrementAndGet();
              } else {
                // is another thread has since done an add and shifted us into a collection
                retry = true;
              }
            }
          } else {
            Collection entries = (Collection) regionEntries;
            if (DefaultQuery.testHook != null) {
              DefaultQuery.testHook
                  .doTestHook(DefaultQuery.TestHook.SPOTS.BEGIN_REMOVE_FROM_ELEM_ARRAY, null, null);
            }
            found = entries.remove(entry);
            if (DefaultQuery.testHook != null) {
              DefaultQuery.testHook
                  .doTestHook(DefaultQuery.TestHook.SPOTS.REMOVE_CALLED_FROM_ELEM_ARRAY, null,
                      null);
            }
            // This could be IndexElementArray and might be changing to Set
            // If the remove occurred before changing to a set, then next time it will not be
            // "found"
            // However the end effect would be that it was removed
            if (entries instanceof IndexElemArray) {
              if (!valueToEntriesMap.replace(newKey, entries, entries)) {
                retry = true;
                possiblyAlreadyRemoved = found;
                continue;
              }
            }

            if (entries.isEmpty()) {
              // because entries collection is empty, remove and decrement
              // value
              synchronized (entries) {
                if (entries.isEmpty()) {
                  if (valueToEntriesMap.remove(newKey, entries)) {
                    if (newKey != IndexManager.NULL && newKey != QueryService.UNDEFINED) {
                      internalIndexStats.incNumKeys(-1);
                    }
                    numIndexKeys.decrementAndGet();
                  }
                }
              }
            }
            if (DefaultQuery.testHook != null) {
              DefaultQuery.testHook
                  .doTestHook(DefaultQuery.TestHook.SPOTS.COMPLETE_REMOVE_FROM_ELEM_ARRAY, null,
                      null);
            }
          }
        }
      } while (retry);
    } catch (TypeMismatchException ex) {
      throw new IMQException("Could not add object of type " + key.getClass().getName(), ex);
    }
    if (found) {
      // Update stats if entry was actually removed
      internalIndexStats.incNumValues(-1);
    } else if (!found && !possiblyAlreadyRemoved && !IndexManager.isObjectModificationInplace()
        && key != null) {
      // if there is an inplace-modification find old key by iterating
      // over fwd map and then remove the mapping
      if (findOldKey) {
        try {
          Object oldKey = getOldKey(key, entry);
          found = basicRemoveMapping(oldKey, entry, false);
        } catch (TypeMismatchException e) {
          throw new IMQException("Could not find old key: " + key.getClass().getName(), e);
        }
      }
    }
    return found;
  }
Find the old key by traversing the forward map in case of in-place update modification If not
found it means the value object was modified with same value. So oldKey is same as newKey.
geode-core/src/main/java/org/apache/geode/cache/query/internal/index/MemoryIndexStore.java