LCOV - code coverage report
Current view: top level - server/cache - CacheModule.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 51 51 100.0 %
Date: 2022-11-19 15:00:39 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2009 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.cache;
      16             : 
      17             : import com.google.common.cache.Cache;
      18             : import com.google.common.cache.CacheLoader;
      19             : import com.google.common.cache.LoadingCache;
      20             : import com.google.common.cache.Weigher;
      21             : import com.google.gerrit.extensions.annotations.Exports;
      22             : import com.google.gerrit.extensions.config.FactoryModule;
      23             : import com.google.gerrit.server.cache.serialize.JavaCacheSerializer;
      24             : import com.google.inject.Key;
      25             : import com.google.inject.Provider;
      26             : import com.google.inject.Scopes;
      27             : import com.google.inject.TypeLiteral;
      28             : import com.google.inject.name.Named;
      29             : import com.google.inject.name.Names;
      30             : import com.google.inject.util.Types;
      31             : import java.lang.reflect.Type;
      32             : 
      33             : /** Miniature DSL to support binding {@link Cache} instances in Guice. */
      34         152 : public abstract class CacheModule extends FactoryModule {
      35             :   public static final String MEMORY_MODULE = "cache-memory";
      36             :   public static final String PERSISTENT_MODULE = "cache-persistent";
      37             : 
      38         152 :   private static final TypeLiteral<Cache<?, ?>> ANY_CACHE = new TypeLiteral<>() {};
      39             : 
      40             :   /**
      41             :    * Declare a named in-memory cache.
      42             :    *
      43             :    * @param <K> type of key used to lookup entries.
      44             :    * @param <V> type of value stored by the cache.
      45             :    * @return binding to describe the cache.
      46             :    */
      47             :   protected <K, V> CacheBinding<K, V> cache(String name, Class<K> keyType, Class<V> valType) {
      48         152 :     return cache(name, TypeLiteral.get(keyType), TypeLiteral.get(valType));
      49             :   }
      50             : 
      51             :   /**
      52             :    * Declare a named in-memory cache.
      53             :    *
      54             :    * @param <K> type of key used to lookup entries.
      55             :    * @param <V> type of value stored by the cache.
      56             :    * @return binding to describe the cache.
      57             :    */
      58             :   protected <K, V> CacheBinding<K, V> cache(String name, Class<K> keyType, TypeLiteral<V> valType) {
      59         152 :     return cache(name, TypeLiteral.get(keyType), valType);
      60             :   }
      61             : 
      62             :   /**
      63             :    * Declare a named in-memory cache.
      64             :    *
      65             :    * @param <K> type of key used to lookup entries.
      66             :    * @param <V> type of value stored by the cache.
      67             :    * @return binding to describe the cache.
      68             :    */
      69             :   protected <K, V> CacheBinding<K, V> cache(
      70             :       String name, TypeLiteral<K> keyType, TypeLiteral<V> valType) {
      71         152 :     CacheProvider<K, V> m = new CacheProvider<>(this, name, keyType, valType);
      72         152 :     bindCache(m, name, keyType, valType);
      73         152 :     return m;
      74             :   }
      75             : 
      76             :   <K, V> Provider<CacheLoader<K, V>> bindCacheLoader(
      77             :       CacheProvider<K, V> m, Class<? extends CacheLoader<K, V>> impl) {
      78         152 :     Type type =
      79         152 :         Types.newParameterizedType(Cache.class, m.keyType().getType(), m.valueType().getType());
      80             : 
      81         152 :     Type loadingType =
      82         152 :         Types.newParameterizedType(
      83         152 :             LoadingCache.class, m.keyType().getType(), m.valueType().getType());
      84             : 
      85         152 :     Type loaderType =
      86         152 :         Types.newParameterizedType(
      87         152 :             CacheLoader.class, m.keyType().getType(), m.valueType().getType());
      88             : 
      89             :     @SuppressWarnings("unchecked")
      90         152 :     Key<LoadingCache<K, V>> key = (Key<LoadingCache<K, V>>) Key.get(type, Names.named(m.name));
      91             : 
      92             :     @SuppressWarnings("unchecked")
      93         152 :     Key<LoadingCache<K, V>> loadingKey =
      94         152 :         (Key<LoadingCache<K, V>>) Key.get(loadingType, Names.named(m.name));
      95             : 
      96             :     @SuppressWarnings("unchecked")
      97         152 :     Key<CacheLoader<K, V>> loaderKey =
      98         152 :         (Key<CacheLoader<K, V>>) Key.get(loaderType, Names.named(m.name));
      99             : 
     100         152 :     bind(loaderKey).to(impl).in(Scopes.SINGLETON);
     101         152 :     bind(loadingKey).to(key);
     102         152 :     return getProvider(loaderKey);
     103             :   }
     104             : 
     105             :   <K, V> Provider<Weigher<K, V>> bindWeigher(
     106             :       CacheProvider<K, V> m, Class<? extends Weigher<K, V>> impl) {
     107         152 :     Type weigherType =
     108         152 :         Types.newParameterizedType(Weigher.class, m.keyType().getType(), m.valueType().getType());
     109             : 
     110             :     @SuppressWarnings("unchecked")
     111         152 :     Key<Weigher<K, V>> key = (Key<Weigher<K, V>>) Key.get(weigherType, Names.named(m.name));
     112             : 
     113         152 :     bind(key).to(impl).in(Scopes.SINGLETON);
     114         152 :     return getProvider(key);
     115             :   }
     116             : 
     117             :   /**
     118             :    * Declare a named in-memory/on-disk cache.
     119             :    *
     120             :    * @param <K> type of key used to lookup entries.
     121             :    * @param <V> type of value stored by the cache.
     122             :    * @return binding to describe the cache.
     123             :    */
     124             :   protected <K, V> PersistentCacheBinding<K, V> persist(
     125             :       String name, Class<K> keyType, Class<V> valType) {
     126         152 :     return persist(name, TypeLiteral.get(keyType), TypeLiteral.get(valType));
     127             :   }
     128             : 
     129             :   /**
     130             :    * Declare a named in-memory/on-disk cache.
     131             :    *
     132             :    * @param <K> type of key used to lookup entries.
     133             :    * @param <V> type of value stored by the cache.
     134             :    * @return binding to describe the cache.
     135             :    */
     136             :   protected <K, V> PersistentCacheBinding<K, V> persist(
     137             :       String name, Class<K> keyType, TypeLiteral<V> valType) {
     138         152 :     return persist(name, TypeLiteral.get(keyType), valType);
     139             :   }
     140             : 
     141             :   /**
     142             :    * Declare a named in-memory/on-disk cache.
     143             :    *
     144             :    * @param <K> type of key used to lookup entries.
     145             :    * @param <V> type of value stored by the cache.
     146             :    * @return binding to describe the cache.
     147             :    */
     148             :   protected <K, V> PersistentCacheBinding<K, V> persist(
     149             :       String name, TypeLiteral<K> keyType, TypeLiteral<V> valType) {
     150         152 :     PersistentCacheProvider<K, V> m = new PersistentCacheProvider<>(this, name, keyType, valType);
     151         152 :     bindCache(m, name, keyType, valType);
     152             : 
     153         152 :     Type cacheDefType =
     154         152 :         Types.newParameterizedType(PersistentCacheDef.class, keyType.getType(), valType.getType());
     155             :     @SuppressWarnings("unchecked")
     156         152 :     Key<PersistentCacheDef<K, V>> cacheDefKey =
     157         152 :         (Key<PersistentCacheDef<K, V>>) Key.get(cacheDefType, Names.named(name));
     158         152 :     bind(cacheDefKey).toInstance(m);
     159             : 
     160             :     // TODO(dborowitz): Once default Java serialization is removed, leave no default.
     161         152 :     return m.version(0)
     162         152 :         .keySerializer(new JavaCacheSerializer<>())
     163         152 :         .valueSerializer(new JavaCacheSerializer<>());
     164             :   }
     165             : 
     166             :   private <K, V> void bindCache(
     167             :       CacheProvider<K, V> m, String name, TypeLiteral<K> keyType, TypeLiteral<V> valType) {
     168         152 :     Type type = Types.newParameterizedType(Cache.class, keyType.getType(), valType.getType());
     169         152 :     Named named = Names.named(name);
     170             : 
     171             :     @SuppressWarnings("unchecked")
     172         152 :     Key<Cache<K, V>> key = (Key<Cache<K, V>>) Key.get(type, named);
     173         152 :     bind(key).toProvider(m).asEagerSingleton();
     174         152 :     bind(ANY_CACHE).annotatedWith(Exports.named(name)).to(key);
     175             : 
     176         152 :     Type cacheDefType =
     177         152 :         Types.newParameterizedType(CacheDef.class, keyType.getType(), valType.getType());
     178             :     @SuppressWarnings("unchecked")
     179         152 :     Key<CacheDef<K, V>> cacheDefKey = (Key<CacheDef<K, V>>) Key.get(cacheDefType, named);
     180         152 :     bind(cacheDefKey).toInstance(m);
     181             : 
     182         152 :     m.maximumWeight(1024);
     183         152 :   }
     184             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750