Line data Source code
1 : // Copyright (C) 2018 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 static com.google.common.base.Preconditions.checkState;
18 :
19 : import com.google.common.cache.Cache;
20 : import com.google.common.cache.CacheLoader;
21 : import com.google.common.cache.Weigher;
22 : import com.google.gerrit.common.Nullable;
23 : import com.google.gerrit.server.cache.serialize.CacheSerializer;
24 : import com.google.gerrit.server.cache.serialize.JavaCacheSerializer;
25 : import com.google.inject.Inject;
26 : import com.google.inject.Provider;
27 : import com.google.inject.TypeLiteral;
28 : import java.io.Serializable;
29 : import java.time.Duration;
30 :
31 : class PersistentCacheProvider<K, V> extends CacheProvider<K, V>
32 : implements Provider<Cache<K, V>>, PersistentCacheBinding<K, V>, PersistentCacheDef<K, V> {
33 : private int version;
34 : private long diskLimit;
35 : private CacheSerializer<K> keySerializer;
36 : private CacheSerializer<V> valueSerializer;
37 :
38 : private PersistentCacheFactory persistentCacheFactory;
39 :
40 : PersistentCacheProvider(
41 : CacheModule module, String name, TypeLiteral<K> keyType, TypeLiteral<V> valType) {
42 152 : super(module, name, keyType, valType);
43 152 : version = -1;
44 152 : diskLimit = 128 << 20;
45 152 : }
46 :
47 : @Inject(optional = true)
48 : void setPersistentCacheFactory(@Nullable PersistentCacheFactory factory) {
49 152 : this.persistentCacheFactory = factory;
50 152 : }
51 :
52 : @Override
53 : public PersistentCacheBinding<K, V> maximumWeight(long weight) {
54 152 : return (PersistentCacheBinding<K, V>) super.maximumWeight(weight);
55 : }
56 :
57 : @Override
58 : public PersistentCacheBinding<K, V> expireAfterWrite(Duration duration) {
59 99 : return (PersistentCacheBinding<K, V>) super.expireAfterWrite(duration);
60 : }
61 :
62 : @Override
63 : public PersistentCacheBinding<K, V> loader(Class<? extends CacheLoader<K, V>> clazz) {
64 152 : return (PersistentCacheBinding<K, V>) super.loader(clazz);
65 : }
66 :
67 : @Override
68 : public PersistentCacheBinding<K, V> expireFromMemoryAfterAccess(Duration duration) {
69 152 : return (PersistentCacheBinding<K, V>) super.expireFromMemoryAfterAccess(duration);
70 : }
71 :
72 : @Override
73 : public PersistentCacheBinding<K, V> weigher(Class<? extends Weigher<K, V>> clazz) {
74 152 : return (PersistentCacheBinding<K, V>) super.weigher(clazz);
75 : }
76 :
77 : @Override
78 : public PersistentCacheBinding<K, V> version(int version) {
79 152 : this.version = version;
80 152 : return this;
81 : }
82 :
83 : @Override
84 : public PersistentCacheBinding<K, V> keySerializer(CacheSerializer<K> keySerializer) {
85 152 : this.keySerializer = keySerializer;
86 152 : return this;
87 : }
88 :
89 : @Override
90 : public PersistentCacheBinding<K, V> valueSerializer(CacheSerializer<V> valueSerializer) {
91 152 : this.valueSerializer = valueSerializer;
92 152 : return this;
93 : }
94 :
95 : @Override
96 : public PersistentCacheBinding<K, V> diskLimit(long limit) {
97 152 : checkNotFrozen();
98 152 : diskLimit = limit;
99 152 : return this;
100 : }
101 :
102 : @Override
103 : public long diskLimit() {
104 151 : return diskLimit;
105 : }
106 :
107 : @Override
108 : public int version() {
109 15 : return version;
110 : }
111 :
112 : @Override
113 : public CacheSerializer<K> keySerializer() {
114 15 : return keySerializer;
115 : }
116 :
117 : @Override
118 : public CacheSerializer<V> valueSerializer() {
119 15 : return valueSerializer;
120 : }
121 :
122 : @Override
123 : public Cache<K, V> get() {
124 152 : if (persistentCacheFactory == null) {
125 0 : return super.get();
126 : }
127 152 : checkState(version >= 0, "version is required");
128 152 : checkSerializer(keyType(), keySerializer, "key");
129 152 : checkSerializer(valueType(), valueSerializer, "value");
130 152 : freeze();
131 152 : CacheLoader<K, V> ldr = loader();
132 152 : return ldr != null
133 152 : ? persistentCacheFactory.build(this, ldr)
134 152 : : persistentCacheFactory.build(this);
135 : }
136 :
137 : private static <T> void checkSerializer(
138 : TypeLiteral<T> type, CacheSerializer<T> serializer, String name) {
139 152 : checkState(serializer != null, "%sSerializer is required", name);
140 152 : if (serializer instanceof JavaCacheSerializer) {
141 152 : checkState(
142 152 : Serializable.class.isAssignableFrom(type.getRawType()),
143 : "%s type %s must implement Serializable",
144 : name,
145 : type);
146 : }
147 152 : }
148 : }
|