private void release(IdentityArrayList localLocks, boolean conflictDetected) {
    final int llSize = localLocks.size();
    final Object[] llArray = localLocks.getArrayRef();

    for (int i = 0; i < llSize; i++) {
      TXRegionLockRequestImpl rr = (TXRegionLockRequestImpl) llArray[i];
      Object r = getRegionObject(rr);
      Map<Object, Boolean> keys = rr.getKeys();

      Object curValue = regionLocks.get(r);
      boolean foundIt = false;
      if (curValue != null) {
        if (curValue == keys) {
          foundIt = true;
          regionLocks.remove(r);

        } else if (curValue instanceof IdentityArrayList) {

          IdentityArrayList al = (IdentityArrayList) curValue;
          int idx = al.indexOf(keys);
          if (idx != -1) {
            foundIt = true;
            al.remove(idx);
            if (al.isEmpty()) {
              regionLocks.remove(r);
            } else {
              regionLocks.put(r, al);
            }
          }
        }
      }
      if (!foundIt && conflictDetected) {
        // No need to process the rest since the will not be found either
        // All we need to do is release the ones obtained before the
        // conflict was detected.
        break;
      }
    }
  }
keys are LocalRegion; values are ArrayList of Sets of held locks.
geode-core/src/main/java/org/apache/geode/internal/cache/TXReservationMgr.java