001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.collections;
018
019/**
020 * Cache modes for {@link Cache} and related cache classes.
021 *
022 * <p>
023 * Defines how cache storage is implemented and when cached entries may be evicted.
024 *
025 * <h5 class='section'>See Also:</h5>
026 * <ul>
027 *    <li class='jc'>{@link Cache}
028 *    <li class='jc'>{@link Cache2}
029 *    <li class='jc'>{@link Cache3}
030 *    <li class='jc'>{@link Cache4}
031 *    <li class='jc'>{@link Cache5}
032 * </ul>
033 */
034public enum CacheMode {
035
036   /**
037    * No caching - all lookups invoke the supplier.
038    *
039    * <p>
040    * When this mode is used, the cache will not store any values. Every call to
041    * {@link Cache#get(Object)} or {@link Cache#get(Object, java.util.function.Supplier)}
042    * will invoke the supplier to compute the value.
043    *
044    * <p>
045    * This mode is useful for:
046    * <ul>
047    *    <li>Testing scenarios where you want fresh computation each time
048    *    <li>Development environments where caching might hide issues
049    *    <li>Temporarily disabling caching without code changes
050    * </ul>
051    */
052   NONE,
053
054   /**
055    * Weak caching - uses {@link java.util.WeakHashMap} for storage.
056    *
057    * <p>
058    * Cache entries can be garbage collected when keys are no longer strongly referenced elsewhere.
059    * The WeakHashMap is wrapped with {@link java.util.Collections#synchronizedMap(java.util.Map)}
060    * for thread safety.
061    *
062    * <p>
063    * This mode is useful for:
064    * <ul>
065    *    <li>Caching metadata about objects that may be unloaded (e.g., {@link Class} objects)
066    *    <li>Memory-sensitive applications where cache entries should not prevent garbage collection
067    *    <li>Scenarios where keys have limited lifetimes
068    * </ul>
069    *
070    * <p>
071    * <b>Note:</b> Weak caching comes with performance trade-offs:
072    * <ul>
073    *    <li>Slightly slower access due to synchronization overhead
074    *    <li>Entries may be removed unpredictably by the garbage collector
075    *    <li>Not suitable for high-concurrency scenarios
076    * </ul>
077    */
078   WEAK,
079
080   /**
081    * Full caching - uses {@link java.util.concurrent.ConcurrentHashMap} for storage.
082    *
083    * <p>
084    * Provides the best performance with lock-free reads and writes. Cached entries
085    * will remain in memory until explicitly removed or the cache is cleared due to
086    * exceeding the maximum size.
087    *
088    * <p>
089    * This is the default and recommended mode for most use cases, offering:
090    * <ul>
091    *    <li>Excellent performance with no synchronization overhead for reads
092    *    <li>Thread-safe concurrent access
093    *    <li>Predictable memory usage (entries stay until evicted)
094    *    <li>Suitable for high-concurrency scenarios
095    * </ul>
096    */
097   FULL;
098
099   /**
100    * Parses a string value into a {@link CacheMode}.
101    *
102    * <p>
103    * Performs case-insensitive matching against the enum constant names.
104    *
105    * <h5 class='section'>Examples:</h5>
106    * <p class='bjava'>
107    *    CacheMode.<jsm>parse</jsm>(<js>"none"</js>);  <jc>// Returns NONE</jc>
108    *    CacheMode.<jsm>parse</jsm>(<js>"WEAK"</js>);  <jc>// Returns WEAK</jc>
109    *    CacheMode.<jsm>parse</jsm>(<js>"Full"</js>);  <jc>// Returns FULL</jc>
110    *    CacheMode.<jsm>parse</jsm>(<jk>null</jk>);    <jc>// Returns FULL (default)</jc>
111    *    CacheMode.<jsm>parse</jsm>(<js>"invalid"</js>); <jc>// Returns FULL (default)</jc>
112    * </p>
113    *
114    * @param value The string value to parse. Can be <jk>null</jk>.
115    * @return The corresponding {@link CacheMode}, or {@link #FULL} if the value is <jk>null</jk> or invalid.
116    */
117   public static CacheMode parse(String value) {
118      if (value == null)
119         return FULL;
120      return switch (value.toUpperCase()) {
121         case "NONE" -> NONE;
122         case "WEAK" -> WEAK;
123         case "FULL" -> FULL;
124         default -> FULL;
125      };
126   }
127}