• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ben-manes / caffeine / #5156

03 Dec 2025 03:21AM UTC coverage: 0.0% (-100.0%) from 100.0%
#5156

push

github

ben-manes
add loading type to parameterized test dimensions to reduce task size

0 of 3834 branches covered (0.0%)

0 of 7848 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/caffeine/src/main/java/com/github/benmanes/caffeine/cache/NodeFactory.java
1
/*
2
 * Copyright 2015 Ben Manes. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.github.benmanes.caffeine.cache;
17

18
import java.lang.invoke.MethodHandles;
19
import java.lang.invoke.MethodType;
20
import java.lang.ref.ReferenceQueue;
21
import java.util.concurrent.ConcurrentHashMap;
22
import java.util.concurrent.ConcurrentMap;
23

24
import com.github.benmanes.caffeine.cache.References.LookupKeyReference;
25
import com.github.benmanes.caffeine.cache.References.WeakKeyReference;
26
import com.google.errorprone.annotations.Var;
27

28
/**
29
 * A factory for cache nodes optimized for a particular configuration.
30
 *
31
 * @author ben.manes@gmail.com (Ben Manes)
32
 */
33
interface NodeFactory<K, V> {
34
  MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
×
35
  MethodType FACTORY = MethodType.methodType(void.class);
×
36
  ConcurrentMap<String, NodeFactory<Object, Object>> FACTORIES = new ConcurrentHashMap<>();
×
37

38
  RetiredStrongKey RETIRED_STRONG_KEY = new RetiredStrongKey();
×
39
  RetiredWeakKey RETIRED_WEAK_KEY = new RetiredWeakKey();
×
40
  DeadStrongKey DEAD_STRONG_KEY = new DeadStrongKey();
×
41
  DeadWeakKey DEAD_WEAK_KEY = new DeadWeakKey();
×
42
  String ACCESS_TIME = "accessTime";
43
  String WRITE_TIME = "writeTime";
44
  String VALUE = "value";
45
  String KEY = "key";
46

47
  /** Returns whether this factory supports weak values. */
48
  default boolean weakValues() {
49
    return false;
×
50
  }
51

52
  /** Returns whether this factory supports soft values. */
53
  default boolean softValues() {
54
    return false;
×
55
  }
56

57
  /** Returns a node optimized for the specified features. */
58
  Node<K, V> newNode(K key, ReferenceQueue<K> keyReferenceQueue, V value,
59
      ReferenceQueue<V> valueReferenceQueue, int weight, long now);
60

61
  /** Returns a node optimized for the specified features. */
62
  Node<K, V> newNode(Object keyReference, V value,
63
      ReferenceQueue<V> valueReferenceQueue, int weight, long now);
64

65
  /**
66
   * Returns a key suitable for inserting into the cache. If the cache holds keys strongly then the
67
   * key is returned. If the cache holds keys weakly then a {@link java.lang.ref.Reference<K>}
68
   * holding the key argument is returned.
69
   */
70
  default Object newReferenceKey(K key, ReferenceQueue<K> referenceQueue) {
71
    return key;
×
72
  }
73

74
  /**
75
   * Returns a key suitable for looking up an entry in the cache. If the cache holds keys strongly
76
   * then the key is returned. If the cache holds keys weakly then a {@link LookupKeyReference}
77
   * holding the key argument is returned.
78
   */
79
  default Object newLookupKey(Object key) {
80
    return key;
×
81
  }
82

83
  /** Returns a factory optimized for the specified features. */
84
  @SuppressWarnings("unchecked")
85
  static <K, V> NodeFactory<K, V> newFactory(Caffeine<K, V> builder, boolean isAsync) {
86
    if (builder.interner) {
×
87
      return (NodeFactory<K, V>) Interned.FACTORY;
×
88
    }
89
    var className = getClassName(builder, isAsync);
×
90
    return loadFactory(className);
×
91
  }
92

93
  static String getClassName(Caffeine<?, ?> builder, boolean isAsync) {
94
    var className = new StringBuilder();
×
95
    if (builder.isStrongKeys()) {
×
96
      className.append('P');
×
97
    } else {
98
      className.append('F');
×
99
    }
100
    if (builder.isStrongValues()) {
×
101
      className.append('S');
×
102
    } else if (builder.isWeakValues()) {
×
103
      className.append('W');
×
104
    } else {
105
      className.append('D');
×
106
    }
107
    if (builder.expiresVariable()) {
×
108
      if (builder.refreshAfterWrite()) {
×
109
        className.append('A');
×
110
        if (builder.evicts()) {
×
111
          className.append('W');
×
112
        }
113
      } else {
114
        className.append('W');
×
115
      }
116
    } else {
117
      if (builder.expiresAfterAccess()) {
×
118
        className.append('A');
×
119
      }
120
      if (builder.expiresAfterWrite()) {
×
121
        className.append('W');
×
122
      }
123
    }
124
    if (builder.refreshAfterWrite()) {
×
125
      className.append('R');
×
126
    }
127
    if (builder.evicts()) {
×
128
      className.append('M');
×
129
      if (isAsync || (builder.isWeighted() && (builder.weigher != Weigher.singletonWeigher()))) {
×
130
        className.append('W');
×
131
      } else {
132
        className.append('S');
×
133
      }
134
    }
135
    return className.toString();
×
136
  }
137

138
  @SuppressWarnings("unchecked")
139
  static <K, V> NodeFactory<K, V> loadFactory(String className) {
140
    @Var var factory = FACTORIES.get(className);
×
141
    if (factory == null) {
×
142
      factory = FACTORIES.computeIfAbsent(className, NodeFactory::newFactory);
×
143
    }
144
    return (NodeFactory<K, V>) factory;
×
145
  }
146

147
  @SuppressWarnings("unchecked")
148
  static NodeFactory<Object, Object> newFactory(String className) {
149
    try {
150
      var clazz = LOOKUP.findClass(Node.class.getPackageName() + "." + className);
×
151
      var constructor = LOOKUP.findConstructor(clazz, FACTORY);
×
152
      return (NodeFactory<Object, Object>) constructor.invoke();
×
153
    } catch (RuntimeException | Error e) {
×
154
      throw e;
×
155
    } catch (Throwable t) {
×
156
      throw new IllegalStateException(className, t);
×
157
    }
158
  }
159

160
  final class RetiredWeakKey extends WeakKeyReference<Object> {
161
    RetiredWeakKey() { super(/* key= */ null, /* queue= */ null); }
×
162
  }
163
  final class DeadWeakKey extends WeakKeyReference<Object> {
164
    DeadWeakKey() { super(/* key= */ null, /* queue= */ null); }
×
165
  }
166
  final class RetiredStrongKey {}
×
167
  final class DeadStrongKey {}
×
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc