Skip to content

Commit

Permalink
First draft (settings not functional)
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Alfonsi <[email protected]>
  • Loading branch information
Peter Alfonsi committed Nov 19, 2024
1 parent f105e4e commit 60d53ce
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.opensearch.cache;

import org.opensearch.cache.store.disk.EhcacheDiskCache;
import org.opensearch.cache.store.disk.EhcacheTieredCache;
import org.opensearch.common.cache.CacheType;
import org.opensearch.common.cache.ICache;
import org.opensearch.common.settings.Setting;
Expand All @@ -35,13 +36,21 @@ public EhcacheCachePlugin() {}

@Override
public Map<String, ICache.Factory> getCacheFactoryMap() {
return Map.of(EhcacheDiskCache.EhcacheDiskCacheFactory.EHCACHE_DISK_CACHE_NAME, new EhcacheDiskCache.EhcacheDiskCacheFactory());
return Map.of(
EhcacheDiskCache.EhcacheDiskCacheFactory.EHCACHE_DISK_CACHE_NAME, new EhcacheDiskCache.EhcacheDiskCacheFactory(),
EhcacheTieredCache.EhcacheTieredCacheFactory.EHCACHE_TIERED_CACHE_NAME, new EhcacheTieredCache.EhcacheTieredCacheFactory()
);
}

@Override
public List<Setting<?>> getSettings() {
List<Setting<?>> settingList = new ArrayList<>();
for (Map.Entry<CacheType, Map<String, Setting<?>>> entry : CACHE_TYPE_MAP.entrySet()) {
for (Map.Entry<CacheType, Map<String, Setting<?>>> entry : EhcacheDiskCacheSettings.CACHE_TYPE_MAP.entrySet()) {
for (Map.Entry<String, Setting<?>> entry1 : entry.getValue().entrySet()) {
settingList.add(entry1.getValue());
}
}
for (Map.Entry<CacheType, Map<String, Setting<?>>> entry : EhcacheTieredCacheSettings.CACHE_TYPE_MAP.entrySet()) {
for (Map.Entry<String, Setting<?>> entry1 : entry.getValue().entrySet()) {
settingList.add(entry1.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public class EhcacheDiskCacheSettings {
* Used to form concrete setting for cache types and return desired map
* @return map of cacheType and associated settings.
*/
private static final Map<CacheType, Map<String, Setting<?>>> getCacheTypeMap() {
protected static Map<CacheType, Map<String, Setting<?>>> getCacheTypeMap() {
Map<CacheType, Map<String, Setting<?>>> cacheTypeMap = new HashMap<>();
for (CacheType cacheType : CacheType.values()) {
Map<String, Setting<?>> settingMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.cache;

import org.opensearch.cache.store.disk.EhcacheDiskCache;
import org.opensearch.cache.store.disk.EhcacheTieredCache;
import org.opensearch.common.cache.CacheType;
import org.opensearch.common.settings.Setting;

import java.util.HashMap;
import java.util.Map;

import static org.opensearch.common.settings.Setting.Property.NodeScope;

/**
* Settings related to EhcacheTieredCache.
*/
public class EhcacheTieredCacheSettings {
// TODO: Since I can't override a static suffix for the settings, for now it's just gonna use ehcache_disk settings where appropriate.
// This can be fixed later on if needed.

/**
* Default cache size in bytes ie 1gb.
*/
public static final long DEFAULT_HEAP_CACHE_SIZE_IN_BYTES = 10_485_760L; // 10 MB

/**
* Heap cache max size setting.
*/
public static final Setting.AffixSetting<Long> HEAP_CACHE_MAX_SIZE_IN_BYTES_SETTING = Setting.suffixKeySetting(
EhcacheTieredCache.EhcacheTieredCacheFactory.EHCACHE_TIERED_CACHE_NAME + ".heap_max_size_in_bytes",
(key) -> Setting.longSetting(key, DEFAULT_HEAP_CACHE_SIZE_IN_BYTES, NodeScope)
);

/**
* Key for max size.
*/
public static final String HEAP_CACHE_MAX_SIZE_IN_BYTES_KEY = "heap_max_size_in_bytes";

private static final Map<String, Setting.AffixSetting<?>> KEY_SETTING_MAP = Map.of(
HEAP_CACHE_MAX_SIZE_IN_BYTES_KEY,
HEAP_CACHE_MAX_SIZE_IN_BYTES_SETTING
);

/**
* Map to store desired settings for a cache type.
*/
public static final Map<CacheType, Map<String, Setting<?>>> CACHE_TYPE_MAP = getCacheTypeMap();

/**
* Used to form concrete setting for cache types and return desired map
* @return map of cacheType and associated settings.
* // TODO: Duplicated from other settings, but currently not extending those...
*/
protected static Map<CacheType, Map<String, Setting<?>>> getCacheTypeMap() {
Map<CacheType, Map<String, Setting<?>>> cacheTypeMap = new HashMap<>();
for (CacheType cacheType : CacheType.values()) {
Map<String, Setting<?>> settingMap = new HashMap<>();
for (Map.Entry<String, Setting.AffixSetting<?>> entry : KEY_SETTING_MAP.entrySet()) {
settingMap.put(entry.getKey(), entry.getValue().getConcreteSettingForNamespace(cacheType.getSettingPrefix()));
}
cacheTypeMap.put(cacheType, settingMap);
}
return cacheTypeMap;
}

/**
* Fetches setting list for a combination of cache type and store name.
* @param cacheType cache type
* @return settings
* // tODO: cant override this bc static. So not extending other settings for now.
*/
public static final Map<String, Setting<?>> getSettingListForCacheType(CacheType cacheType) {
Map<String, Setting<?>> cacheTypeSettings = CACHE_TYPE_MAP.get(cacheType);
if (cacheTypeSettings == null) {
throw new IllegalArgumentException(
"No settings exist for cache store name: "
+ EhcacheDiskCache.EhcacheDiskCacheFactory.EHCACHE_DISK_CACHE_NAME
+ "associated with "
+ "cache type: "
+ cacheType
);
}
return cacheTypeSettings;
}

/**
* Default constructor. Added to fix javadocs.
*/
public EhcacheTieredCacheSettings() {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public class EhcacheDiskCache<K, V> implements ICache<K, V> {
private static final Logger logger = LogManager.getLogger(EhcacheDiskCache.class);

// Unique id associated with this cache.
final static String UNIQUE_ID = UUID.randomUUID().toString();
final static String THREAD_POOL_ALIAS_PREFIX = "ehcachePool";
private final static String UNIQUE_ID = UUID.randomUUID().toString();
private final static String THREAD_POOL_ALIAS_PREFIX = "ehcachePool";
final static int MINIMUM_MAX_SIZE_IN_BYTES = 1024 * 100; // 100KB
final static String CACHE_DATA_CLEANUP_DURING_INITIALIZATION_EXCEPTION = "Failed to delete ehcache disk cache under "
+ "path: %s during initialization. Please clean this up manually and restart the process";
Expand All @@ -113,7 +113,10 @@ public class EhcacheDiskCache<K, V> implements ICache<K, V> {
// Disk cache. Using ByteArrayWrapper to compare two byte[] by values rather than the default reference checks
@SuppressWarnings({ "rawtypes" }) // We have to use the raw type as there's no way to pass the "generic class" to ehcache
private final Cache<ICacheKey, ByteArrayWrapper> cache;
private final long maxWeightInBytes;
/**
* Max weight for disk tier.
*/
protected final long maxWeightInBytes;
private final String storagePath;
private final Class<K> keyType;
private final Class<V> valueType;
Expand Down Expand Up @@ -194,8 +197,22 @@ PersistentCacheManager getCacheManager() {
return this.cacheManager;
}

/**
* Specify resource pools.
* @return
*/
protected ResourcePoolsBuilder getResourcePoolsBuilder() {
return ResourcePoolsBuilder.newResourcePoolsBuilder().disk(maxWeightInBytes, MemoryUnit.B);
}

/**
* Build a cache.
* @param expireAfterAccess
* @param builder
* @return
*/
@SuppressWarnings({ "rawtypes" })
private Cache<ICacheKey, ByteArrayWrapper> buildCache(Duration expireAfterAccess, Builder<K, V> builder) {
protected Cache<ICacheKey, ByteArrayWrapper> buildCache(Duration expireAfterAccess, Builder<K, V> builder) {
// Creating the cache requires permissions specified in plugin-security.policy
return AccessController.doPrivileged((PrivilegedAction<Cache<ICacheKey, ByteArrayWrapper>>) () -> {
try {
Expand All @@ -210,7 +227,7 @@ private Cache<ICacheKey, ByteArrayWrapper> buildCache(Duration expireAfterAccess
CacheConfigurationBuilder.newCacheConfigurationBuilder(
ICacheKey.class,
ByteArrayWrapper.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(maxWeightInBytes, MemoryUnit.B)
getResourcePoolsBuilder()
).withExpiry(new ExpiryPolicy<>() {
@Override
public Duration getExpiryForCreation(ICacheKey key, ByteArrayWrapper value) {
Expand Down Expand Up @@ -664,7 +681,7 @@ public boolean equals(ByteArrayWrapper object, ByteBuffer binary) throws ClassNo
* @param value the value
* @return the serialized value
*/
private ByteArrayWrapper serializeValue(V value) {
protected ByteArrayWrapper serializeValue(V value) {
return new ByteArrayWrapper(valueSerializer.serialize(value));
}

Expand All @@ -673,7 +690,7 @@ private ByteArrayWrapper serializeValue(V value) {
* @param binary the serialized value
* @return the deserialized value
*/
private V deserializeValue(ByteArrayWrapper binary) {
protected V deserializeValue(ByteArrayWrapper binary) {
if (binary == null) {
return null;
}
Expand All @@ -695,9 +712,17 @@ public static class EhcacheDiskCacheFactory implements ICache.Factory {
*/
public EhcacheDiskCacheFactory() {}

@Override
/**
* Setup the builder.
* @param config
* @param cacheType
* @param cacheFactories
* @return
* @param <K>
* @param <V>
*/
@SuppressWarnings({ "unchecked" }) // Required to ensure the serializers output byte[]
public <K, V> ICache<K, V> create(CacheConfig<K, V> config, CacheType cacheType, Map<String, Factory> cacheFactories) {
protected <K, V> Builder<K, V> setupBuilder(CacheConfig<K, V> config, CacheType cacheType, Map<String, Factory> cacheFactories) {
Map<String, Setting<?>> settingList = EhcacheDiskCacheSettings.getSettingListForCacheType(cacheType);
Settings settings = config.getSettings();

Expand Down Expand Up @@ -752,7 +777,13 @@ public <K, V> ICache<K, V> create(CacheConfig<K, V> config, CacheType cacheType,
} else {
builder.setNumberOfSegments(segmentCount);
}
return builder.build();
return builder;
}

@Override
@SuppressWarnings({ "unchecked" }) // Required to ensure the serializers output byte[]
public <K, V> ICache<K, V> create(CacheConfig<K, V> config, CacheType cacheType, Map<String, Factory> cacheFactories) {
return setupBuilder(config, cacheType, cacheFactories).build();
}

@Override
Expand All @@ -768,22 +799,23 @@ public String getCacheName() {
*/
public static class Builder<K, V> extends ICacheBuilder<K, V> {

private CacheType cacheType;
private String storagePath;
// todo: should be protected, but dont want to do javadocs rn
CacheType cacheType;
String storagePath;

private String threadPoolAlias;
String threadPoolAlias;

private String diskCacheAlias;
String diskCacheAlias;

// Provides capability to make ehCache event listener to run in sync mode. Used for testing too.
private boolean isEventListenerModeSync;
boolean isEventListenerModeSync;

private Class<K> keyType;
Class<K> keyType;

private Class<V> valueType;
private List<String> dimensionNames;
private Serializer<K, byte[]> keySerializer;
private Serializer<V, byte[]> valueSerializer;
Class<V> valueType;
List<String> dimensionNames;
Serializer<K, byte[]> keySerializer;
Serializer<V, byte[]> valueSerializer;

/**
* Default constructor. Added to fix javadocs.
Expand Down
Loading

0 comments on commit 60d53ce

Please sign in to comment.