code: private <T extends Metric, V extends MetricProxy<T>> V getOrSet(ConcurrentHashMap<String, V> cache, String name,
                                                                      Function<String, T> createMetric,
                                                                      ProxyCreator<T, V> createProxy, String... tags) {
          // We could simply use Map.computeIfAbsent to do everything atomically, however in ConcurrentHashMap, the function
          // is evaluated while holding the lock. As per the method's guidelines, the computation should be quick and not
          // do any IO or acquire other locks, however we have no control over new Metric creation. As such, we use optimistic
          // concurrency, where we assume that the MetricProxy does not exist, create it, and then if it does exist, close
          // the newly created one.
          MetricsNames.MetricKey keys = metricKey(name, tags);
          T newMetric = createMetric.apply(keys.getRegistryKey());
          V newProxy = createProxy.apply(newMetric, keys.getCacheKey(), cache::remove);
          V existingProxy = cache.putIfAbsent(newProxy.getProxyName(), newProxy);
          if (existingProxy != null) {
              newProxy.close();
              newMetric.close();
              return existingProxy;
          } else {
              return newProxy;
          }
      }
docs: Atomically gets an existing MetricProxy from the given cache or creates a new one and adds it.
  
  @param cache        The Cache to get or insert into.
  @param name         Metric/Proxy name.
  @param createMetric A Function that creates a new Metric given its name.
  @param createProxy  A Function that creates a MetricProxy given its input.
  @param <T>          Type of Metric.
  @param <V>          Type of MetricProxy.
  @return Either the existing MetricProxy (if it is already registered) or the newly created one.