### Description

`SearchResponse.Clusters` currently uses a `HashMap<String, AtomicReference>` for storing Cluster objects. The AtomicReference CAS swaps are done in a do/while loop in most cases (e.g., in `CCSSingleCoordinatorSearchProgressListener`).

This can be replaced with a `ConcurrentHashMap` in conjunction with either `compute()` method or the `replace(key, assumed_previous_value, value)` method for atomically swapping in a new Cluster object with a CAS operation, assuring that the updates don't lose data from competing threads doing separate Cluster object updates.

See: https://github.com/elastic/elasticsearch/pull/98457/files#r1310467586 
server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
true,
                        alias -> remoteClusterService.isSkipUnavailable(alias)
                    );
                    if (localIndices == null) {
                        
                        task.getProgressListener()
                            .notifyListShards(Collections.emptyList(), Collections.emptyList(), clusters, false, timeProvider);
                    }
                    ccsRemoteReduce(
                        parentTaskId,
                        rewritten,
                        localIndices,
                        remoteClusterIndices,
                        clusters,
                        timeProvider,
                        aggregationReduceContextBuilder,
                        remoteClusterService,
                        threadPool,
                        delegate,
                        (r, l) -> executeLocalSearch(
                            task,
                            timeProvider,
                            r,
                            localIndices,
                            clusterState,
                            clusters,
                            searchContext,
                            searchPhaseProvider.apply(l)
                        )
                    );