All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.query.backend.ReadIntensiveClusterRegistryWrapper Maven / Gradle / Ivy

There is a newer version: 9.1.7.Final
Show newest version
package org.infinispan.query.backend;

import net.jcip.annotations.ThreadSafe;
import org.infinispan.registry.ClusterRegistry;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Local cache for the ClusterRegistry.
 * Write operations are expected to happen only exceptionally, therefore this code
 * is heavily optimized for reads (at cost of writes).
 * Also we're assuming all entries are small: there is no size limit nor cleanup strategy.
 *
 * This is not caching the fact that some key is not defined: that would be tricky to
 * get right and is not needed for our use case.
 *
 * @author Sanne Grinovero (C) 2013 Red Hat Inc.
 */
@ThreadSafe
final class ReadIntensiveClusterRegistryWrapper {

   private final ClusterRegistry clusterRegistry;
   private final S scope;

   /**
    * Not using a ConcurrentHashMap as this will degenerate into a read-only Map at runtime;
    * in the Query specific case we're only adding new class types while they are being discovered,
    * after this initial phase this is supposed to be a read-only immutable map.
    */
   private final AtomicReference> localCache = new AtomicReference>(Collections.EMPTY_MAP);

   ReadIntensiveClusterRegistryWrapper(ClusterRegistry clusterRegistry, S scope) {
      this.clusterRegistry = clusterRegistry;
      this.scope = scope;
   }

   void addListener(final Object registryListener) {
      clusterRegistry.addListener(scope, registryListener);
   }

   Set keys() {
      return clusterRegistry.keys(scope);
   }

   void removeListener(final Object registryListener) {
      clusterRegistry.removeListener(registryListener);
   }

   boolean containsKey(final K key) {
      return localCache.get().containsKey(key);
   }

   void put(final K key, final V value) {
      clusterRegistry.put(scope, key, value);
      localCacheInsert(key, value);
   }

   V get(final K key) {
      return localCache.get().get(key);
   }

   private void localCacheInsert(final K key, final V value) {
      synchronized (localCache) {
         final Map currentContent = localCache.get();
         final int currentSize = currentContent.size();
         if (currentSize == 0) {
            localCache.lazySet(Collections.singletonMap(key, value));
         } else {
            Map updatedContent = new HashMap(currentSize + 1);
            updatedContent.putAll(currentContent);
            updatedContent.put(key, value);
            localCache.lazySet(Collections.unmodifiableMap(updatedContent));
         }
      }
   }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy