rgw: group lifecycle versioned deletes to reduce OLH contention
When multiple versions of the same key expire together, each delete
does a read-modify-write of the OLH on the same bucket index shard.
Buffer versions of the same key during listing and flush on key change.
Groups with multiple versions get pre-evaluated, then hard deletes go
through rgw::multi_delete::dispatch() which skips OLH updates on all
but the last delete. LCOpRule::process() is split into evaluate() and
execute() to support this two-phase pattern.
Non-versioned buckets and single-version groups are unchanged.
Signed-off-by: Matthew N. Heler <matthew.heler@hotmail.com>