Murtadha Hubail has submitted this change and it was merged. Change subject: [NO ISSUE][OTH] Introduce NC CacheManager ......................................................................
[NO ISSUE][OTH] Introduce NC CacheManager - user model changes: no - storage format changes: no - interface changes: yes Details: - Introduce NC CacheManager that can be used to cache values and reevaluate them based on cache policy. - Add test case for CacheManager. Change-Id: I8cba7753af11469e8a45cb1d59dfd70c17cd05f6 Reviewed-on: https://asterix-gerrit.ics.uci.edu/3277 Sonar-Qube: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Contrib: Jenkins <[email protected]> Reviewed-by: Michael Blow <[email protected]> --- M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheManager.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheableValue.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheManager.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICachePolicy.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheableValue.java A hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/TimeBasedCachePolicy.java A hyracks-fullstack/hyracks/hyracks-util/src/test/java/org/apache/hyracks/util/cache/CacheManagerTest.java 9 files changed, 337 insertions(+), 0 deletions(-) Approvals: Jenkins: Verified; No violations found; ; Verified Michael Blow: Looks good to me, approved Objections: Anon. E. Moose #1000171: Violations found diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java index 724691c..e663b49 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java @@ -108,6 +108,8 @@ import org.apache.hyracks.storage.common.file.ILocalResourceRepositoryFactory; import org.apache.hyracks.storage.common.file.IResourceIdFactory; import org.apache.hyracks.util.MaintainedThreadNameExecutorService; +import org.apache.hyracks.util.cache.CacheManager; +import org.apache.hyracks.util.cache.ICacheManager; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -149,6 +151,7 @@ private IIndexCheckpointManagerProvider indexCheckpointManagerProvider; private IReplicaManager replicaManager; private IReceptionist receptionist; + private ICacheManager cacheManager; public NCAppRuntimeContext(INCServiceContext ncServiceContext, List<AsterixExtension> extensions, IPropertiesFactory propertiesFactory) throws AsterixException, InstantiationException, @@ -175,6 +178,7 @@ componentProvider = new StorageComponentProvider(); resourceIdFactory = new GlobalResourceIdFactoryProvider(ncServiceContext).createResourceIdFactory(); persistedResourceRegistry = ncServiceContext.getPersistedResourceRegistry(); + cacheManager = new CacheManager(); } @Override @@ -543,4 +547,9 @@ public IReceptionist getReceptionist() { return receptionist; } + + @Override + public ICacheManager getCacheManager() { + return cacheManager; + } } diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java index c6e7439..a18ff93 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INcApplicationContext.java @@ -40,6 +40,7 @@ import org.apache.hyracks.storage.common.ILocalResourceRepository; import org.apache.hyracks.storage.common.buffercache.IBufferCache; import org.apache.hyracks.storage.common.file.IResourceIdFactory; +import org.apache.hyracks.util.cache.ICacheManager; public interface INcApplicationContext extends IApplicationContext { @@ -125,4 +126,11 @@ long getMaxTxnId(); IPersistedResourceRegistry getPersistedResourceRegistry(); + + /** + * Gets the cache manager of this {@link INcApplicationContext} + * + * @return the cache manager + */ + ICacheManager getCacheManager(); } diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheManager.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheManager.java new file mode 100644 index 0000000..6dc2aac --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheManager.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.hyracks.util.annotations.ThreadSafe; + +@ThreadSafe +public class CacheManager implements ICacheManager { + + private final Map<String, ICacheableValue> registry = new ConcurrentHashMap<>(); + + @Override + public void put(String key, ICacheableValue value) { + registry.put(key, value); + value.cache(); + } + + @Override + public Object get(String key) { + final ICacheableValue value = registry.get(key); + if (value == null) { + return null; + } + synchronized (value) { + if (value.getPolicy().expired()) { + value.cache(); + } + return value.get(); + } + } + + @Override + public void invalidate(String key) { + registry.remove(key); + } +} \ No newline at end of file diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheableValue.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheableValue.java new file mode 100644 index 0000000..7da8d50 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/CacheableValue.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +import java.util.function.Supplier; + +public class CacheableValue<T> implements ICacheableValue<T> { + + private final ICachePolicy policy; + private final Supplier<T> supplier; + private T value; + + public CacheableValue(ICachePolicy policy, Supplier<T> supplier) { + this.policy = policy; + this.supplier = supplier; + } + + @Override + public ICachePolicy getPolicy() { + return policy; + } + + @Override + public void cache() { + value = supplier.get(); + policy.cached(); + } + + @Override + public T get() { + return value; + } +} diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheManager.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheManager.java new file mode 100644 index 0000000..bb9f485 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheManager.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +public interface ICacheManager { + + /** + * Puts the key and value in the cache and evaluates the value at the time it is put + * in the cache. + * + * @param key + * @param value + */ + void put(String key, ICacheableValue value); + + /** + * Gets the cached value associated with {@code key} + * + * @param key + * @return + */ + Object get(String key); + + /** + * Invalidates the cached value associated with {@code key} + * + * @param key + */ + void invalidate(String key); +} \ No newline at end of file diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICachePolicy.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICachePolicy.java new file mode 100644 index 0000000..fd9a68c --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICachePolicy.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +public interface ICachePolicy { + + /** + * A flag indicating whether a cached value has expired according to this policy + * + * @return whether the value expired or not + */ + boolean expired(); + + /** + * Notify this cache policy that a value associated with this policy has been cached + */ + void cached(); +} \ No newline at end of file diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheableValue.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheableValue.java new file mode 100644 index 0000000..42c5c66 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/ICacheableValue.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +public interface ICacheableValue<T> { + + /** + * Gets the cache policy + * + * @return the cache policy + */ + ICachePolicy getPolicy(); + + /** + * Caches this value by evaluating its current value + */ + void cache(); + + /** + * Gets the last evaluated value of this cache value + * + * @return the value + */ + T get(); +} diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/TimeBasedCachePolicy.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/TimeBasedCachePolicy.java new file mode 100644 index 0000000..ddc46e5 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/cache/TimeBasedCachePolicy.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +import java.util.concurrent.TimeUnit; + +import org.apache.hyracks.util.annotations.ThreadSafe; + +@ThreadSafe +public class TimeBasedCachePolicy implements ICachePolicy { + + private final long expiryNanos; + private long lastCacheTime; + + private TimeBasedCachePolicy(long expiryNanos) { + this.expiryNanos = expiryNanos; + } + + public static TimeBasedCachePolicy of(long value, TimeUnit unit) { + return new TimeBasedCachePolicy(unit.toNanos(value)); + } + + @Override + public synchronized boolean expired() { + return System.nanoTime() - lastCacheTime >= expiryNanos; + } + + @Override + public synchronized void cached() { + lastCacheTime = System.nanoTime(); + } +} diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/test/java/org/apache/hyracks/util/cache/CacheManagerTest.java b/hyracks-fullstack/hyracks/hyracks-util/src/test/java/org/apache/hyracks/util/cache/CacheManagerTest.java new file mode 100644 index 0000000..4181084 --- /dev/null +++ b/hyracks-fullstack/hyracks/hyracks-util/src/test/java/org/apache/hyracks/util/cache/CacheManagerTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.util.cache; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Assert; +import org.junit.Test; + +public class CacheManagerTest { + + @Test + public void expiryTest() throws Exception { + CacheManager cacheManager = new CacheManager(); + String key = "someKey"; + AtomicInteger realValue = new AtomicInteger(100); + final TimeBasedCachePolicy policy = TimeBasedCachePolicy.of(5, TimeUnit.SECONDS); + cacheManager.put(key, new CacheableValue<>(policy, realValue::get)); + realValue.set(200); + Object cachedValue = null; + for (int i = 0; i < 10; i++) { + cachedValue = cacheManager.get(key); + if ((int) cachedValue == realValue.get()) { + break; + } + TimeUnit.SECONDS.sleep(1); + } + Assert.assertEquals((int) cachedValue, realValue.get()); + } +} -- To view, visit https://asterix-gerrit.ics.uci.edu/3277 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I8cba7753af11469e8a45cb1d59dfd70c17cd05f6 Gerrit-PatchSet: 4 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Blow <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]>
