-
Notifications
You must be signed in to change notification settings - Fork 811
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WW-5355 Integrate W-TinyLfu cache and use by default #766
Changes from 16 commits
74d2fdc
5011a79
9527da5
1573207
6ff7e15
9c932f2
bfb4df1
d245dc5
4700dca
7463e1d
28cc645
793d383
9be23d7
3d5beae
f314b45
9dbea66
7cded18
7afc772
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,52 +15,86 @@ | |
*/ | ||
package com.opensymphony.xwork2.ognl; | ||
|
||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import org.apache.commons.lang3.BooleanUtils; | ||
|
||
/** | ||
* Default OGNL Cache factory implementation. | ||
* <p>Default OGNL Cache factory implementation.</p> | ||
* | ||
* Currently used for Expression cache and BeanInfo cache creation. | ||
* <p>Currently used for Expression cache and BeanInfo cache creation.</p> | ||
* | ||
* @param <Key> The type for the cache key entries | ||
* @param <Key> The type for the cache key entries | ||
* @param <Value> The type for the cache value entries | ||
*/ | ||
public class DefaultOgnlCacheFactory<Key, Value> implements OgnlCacheFactory<Key, Value> { | ||
|
||
private final AtomicBoolean useLRUCache = new AtomicBoolean(false); | ||
private final AtomicInteger cacheMaxSize = new AtomicInteger(25000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Making this factory class thread-safe seemed unnecessary |
||
private static final int DEFAULT_INIT_CAPACITY = 16; | ||
private static final float DEFAULT_LOAD_FACTOR = 0.75f; | ||
|
||
private CacheType defaultCacheType; | ||
private int cacheMaxSize; | ||
|
||
/** | ||
* @deprecated since 6.4.0, use {@link #DefaultOgnlCacheFactory(int, CacheType)} | ||
*/ | ||
@Deprecated | ||
public DefaultOgnlCacheFactory() { | ||
this(10000, CacheType.CAFFEINE_WTLFU); | ||
} | ||
|
||
public DefaultOgnlCacheFactory(int cacheMaxSize, CacheType defaultCacheType) { | ||
this.cacheMaxSize = cacheMaxSize; | ||
this.defaultCacheType = defaultCacheType; | ||
} | ||
|
||
@Override | ||
public OgnlCache<Key, Value> buildOgnlCache() { | ||
return buildOgnlCache(getCacheMaxSize(), 16, 0.75f, getUseLRUCache()); | ||
return buildOgnlCache(getCacheMaxSize(), DEFAULT_INIT_CAPACITY, DEFAULT_LOAD_FACTOR, defaultCacheType); | ||
} | ||
|
||
@Override | ||
public OgnlCache<Key, Value> buildOgnlCache(int evictionLimit, int initialCapacity, float loadFactor, boolean lruCache) { | ||
if (lruCache) { | ||
return new OgnlLRUCache<>(evictionLimit, initialCapacity, loadFactor); | ||
} else { | ||
return new OgnlDefaultCache<>(evictionLimit, initialCapacity, loadFactor); | ||
public OgnlCache<Key, Value> buildOgnlCache(int evictionLimit, | ||
int initialCapacity, | ||
float loadFactor, | ||
CacheType cacheType) { | ||
switch (cacheType) { | ||
case CONCURRENT_BASIC: | ||
return new OgnlDefaultCache<>(evictionLimit, initialCapacity, loadFactor); | ||
case SYNC_LINKED_LRU: | ||
return new OgnlLRUCache<>(evictionLimit, initialCapacity, loadFactor); | ||
case CAFFEINE_WTLFU: | ||
return new OgnlCaffeineCache<>(evictionLimit, initialCapacity); | ||
default: | ||
throw new IllegalArgumentException("Unknown cache type: " + cacheType); | ||
} | ||
} | ||
|
||
@Override | ||
public int getCacheMaxSize() { | ||
return cacheMaxSize.get(); | ||
return cacheMaxSize; | ||
} | ||
|
||
/** | ||
* @deprecated since 6.4.0 | ||
*/ | ||
@Deprecated | ||
protected void setCacheMaxSize(String maxSize) { | ||
cacheMaxSize.set(Integer.parseInt(maxSize)); | ||
cacheMaxSize = Integer.parseInt(maxSize); | ||
} | ||
|
||
@Override | ||
public boolean getUseLRUCache() { | ||
return useLRUCache.get(); | ||
public CacheType getDefaultCacheType() { | ||
return defaultCacheType; | ||
} | ||
|
||
/** | ||
* No effect when {@code useLRUMode} is {@code false} | ||
* | ||
* @deprecated since 6.4.0 | ||
*/ | ||
@Deprecated | ||
protected void setUseLRUCache(String useLRUMode) { | ||
useLRUCache.set(BooleanUtils.toBoolean(useLRUMode)); | ||
if (BooleanUtils.toBoolean(useLRUMode)) { | ||
defaultCacheType = CacheType.SYNC_LINKED_LRU; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,12 +19,52 @@ | |
* Used by {@link com.opensymphony.xwork2.ognl.OgnlUtil} to create appropriate OGNL | ||
* caches based on configuration. | ||
* | ||
* @param <Key> The type for the cache key entries | ||
* @param <Key> The type for the cache key entries | ||
* @param <Value> The type for the cache value entries | ||
*/ | ||
interface OgnlCacheFactory<Key, Value> { | ||
public interface OgnlCacheFactory<Key, Value> { | ||
OgnlCache<Key, Value> buildOgnlCache(); | ||
OgnlCache<Key, Value> buildOgnlCache(int evictionLimit, int initialCapacity, float loadFactor, boolean lruCache); | ||
|
||
/** | ||
* Note that if {@code lruCache} is {@code false}, the cache type could still be LRU if the default cache type is | ||
* configured as such. | ||
* @deprecated since 6.4.0, use {@link #buildOgnlCache(int, int, float, CacheType)} | ||
*/ | ||
@Deprecated | ||
default OgnlCache<Key, Value> buildOgnlCache(int evictionLimit, | ||
int initialCapacity, | ||
float loadFactor, | ||
boolean lruCache) { | ||
return buildOgnlCache(evictionLimit, | ||
initialCapacity, | ||
loadFactor, | ||
lruCache ? CacheType.SYNC_LINKED_LRU : getDefaultCacheType()); | ||
} | ||
|
||
/** | ||
* @param evictionLimit maximum capacity of the cache where applicable for cache type chosen | ||
* @param initialCapacity initial capacity of the cache where applicable for cache type chosen | ||
* @param loadFactor load factor of the cache where applicable for cache type chosen | ||
* @param cacheType type of cache to build | ||
* @return a new cache instance | ||
*/ | ||
OgnlCache<Key, Value> buildOgnlCache(int evictionLimit, int initialCapacity, float loadFactor, CacheType cacheType); | ||
|
||
int getCacheMaxSize(); | ||
boolean getUseLRUCache(); | ||
|
||
/** | ||
* @deprecated since 6.4.0 | ||
*/ | ||
@Deprecated | ||
default boolean getUseLRUCache() { | ||
return CacheType.SYNC_LINKED_LRU.equals(getDefaultCacheType()); | ||
} | ||
|
||
CacheType getDefaultCacheType(); | ||
|
||
enum CacheType { | ||
CONCURRENT_BASIC, | ||
SYNC_LINKED_LRU, | ||
CAFFEINE_WTLFU | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these different implementations of cache layer? Shouldn't this go through the extension point? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wondering the same thing - I was only maintaining the design introduced in #528. I simply replaced Let me look into refactoring this, it will likely be a breaking change though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah given the breaking nature, I'm more inclined to take on this refactor as part of 7.0, all good for me to create a follow-up card for it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! That would make more sense and then we can remove all the properties and leave that to a given implementation. Please create the ticket :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extracted bootstrap constants into a public static final field for reuse by the default Struts configuration provider and any test code as needed. Adding new required constants was previously a pain