As pointed out here at the moment the AsyncIndexUpdate, via SegmentNodeStore.refreshHead passes null in the contentChanged call. This prevents prefiltering from being applied.
Alternatively the AsyncIndexUpdate.mergeWithConcurrencyCheck could provide an explicit ChangeSet representing empty sets for all (paths, names, types, properties), as really an index update shouldn't generate anything of interest for any jcr listener. Not sure if this is always 100% the case but it sounds like a bit of a waste of CPU to collect hidden paths (of the indices) in a ChangeSet which then anyway shouldn't be applicable to any listener. But yes, it would be somewhat of a violation of the general contract to have the ChangeSet represent all changes. Then again, we could argue that hidden paths aren't included.
Chetan Mehrotra, wdyt?