void generateLocalFilterRouting(InternalCacheEvent event) {
    boolean isEntryEvent = event.getOperation().isEntry();
    EntryEventImpl entryEvent = isEntryEvent ? (EntryEventImpl) event : null;

    FilterProfile filterProfile = getFilterProfile();
    FilterInfo routing = event.getLocalFilterInfo();

    if (filterProfile != null && routing == null) {
      boolean lockForCQ = false;
      Object regionEntryObject = null;

      if (isEntryEvent && entryEvent.getRegionEntry() != null) {
        // we should either have the lock on the region entry
        // or the event was elided and CQ processing won't be done on it
        regionEntryObject = entryEvent.getRegionEntry();
        if (!entryEvent.isConcurrencyConflict()) {
          Assert.assertTrue(regionEntryObject != null);
          lockForCQ = true;
        }
      }
      if (isEntryEvent) {
        if (logger.isDebugEnabled()) {
          logger.debug("getting local client routing.");
        }
      }
      if (lockForCQ) {
        synchronized (regionEntryObject) {
          routing = filterProfile.getLocalFilterRouting(event);
        }
      } else {
        routing = filterProfile.getLocalFilterRouting(event);
      }
      event.setLocalFilterInfo(routing);
    }

    // do not send CQ events to clients out of order
    if (routing != null && event.getOperation().isEntry()
        && ((EntryEventImpl) event).isConcurrencyConflict()) {
      if (logger.isDebugEnabled()) {
        logger.debug("clearing CQ routing for event that's in conflict");
      }
      routing.clearCQRouting();
    }
  }
To lower latency, PRs generate the local filter routing in DistributedCacheOperation after
message distribution and before waiting for responses.

Warning: Even if you comment out bucket condition in following method, getLocalRoutingInfo()
does NOT process CQs for bucket regions internally. See
{@link FilterProfile#getFilterRoutingInfoPart2(FilterRoutingInfo, CacheEvent)} .
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java