You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mh...@apache.org on 2019/03/15 16:02:29 UTC

[asterixdb] branch master updated: [NO ISSUE][OTH] Introduce NC CacheManager

This is an automated email from the ASF dual-hosted git repository.

mhubail pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 04dd597  [NO ISSUE][OTH] Introduce NC CacheManager
04dd597 is described below

commit 04dd5977bd798d3f9538931f77b575eac3afec11
Author: Murtadha Hubail <mh...@apache.org>
AuthorDate: Fri Mar 15 10:49:30 2019 +0300

    [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 <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Contrib: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Michael Blow <mb...@apache.org>
---
 .../apache/asterix/app/nc/NCAppRuntimeContext.java |  9 ++++
 .../asterix/common/api/INcApplicationContext.java  |  8 ++++
 .../apache/hyracks/util/cache/CacheManager.java    | 55 ++++++++++++++++++++++
 .../apache/hyracks/util/cache/CacheableValue.java  | 49 +++++++++++++++++++
 .../apache/hyracks/util/cache/ICacheManager.java   | 46 ++++++++++++++++++
 .../apache/hyracks/util/cache/ICachePolicy.java    | 34 +++++++++++++
 .../apache/hyracks/util/cache/ICacheableValue.java | 41 ++++++++++++++++
 .../hyracks/util/cache/TimeBasedCachePolicy.java   | 48 +++++++++++++++++++
 .../hyracks/util/cache/CacheManagerTest.java       | 47 ++++++++++++++++++
 9 files changed, 337 insertions(+)

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.FileMapManager;
 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 @@ public class NCAppRuntimeContext implements INcApplicationContext {
     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 @@ public class NCAppRuntimeContext implements INcApplicationContext {
         componentProvider = new StorageComponentProvider();
         resourceIdFactory = new GlobalResourceIdFactoryProvider(ncServiceContext).createResourceIdFactory();
         persistedResourceRegistry = ncServiceContext.getPersistedResourceRegistry();
+        cacheManager = new CacheManager();
     }
 
     @Override
@@ -543,4 +547,9 @@ public class NCAppRuntimeContext implements INcApplicationContext {
     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.am.lsm.common.api.ILSMMergePolicyFactory;
 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 @@ public interface INcApplicationContext extends IApplicationContext {
     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());
+    }
+}