KYLIN-1843: support LRU cache on SnapshotManager

Signed-off-by: Li Yang <liy...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/6b45c945
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/6b45c945
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/6b45c945

Branch: refs/heads/master
Commit: 6b45c945af9948c17a971d530c0153b3564f1985
Parents: 7dc8b06
Author: Yiming Liu <liuyiming....@gmail.com>
Authored: Thu Jul 7 12:30:25 2016 +0800
Committer: Li Yang <liy...@apache.org>
Committed: Fri Jul 8 18:13:55 2016 +0800

----------------------------------------------------------------------
 .../apache/kylin/common/KylinConfigBase.java    |  4 ++
 .../kylin/dict/lookup/SnapshotManager.java      | 42 +++++++++++++++-----
 2 files changed, 37 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/6b45c945/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
----------------------------------------------------------------------
diff --git 
a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java 
b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index bfbaaa4..6b528f7 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -502,6 +502,10 @@ abstract public class KylinConfigBase implements 
Serializable {
         return Integer.parseInt(getOptional("kylin.dict.cache.max.entry", 
"3000"));
     }
 
+    public int getCachedSnapshotMaxEntrySize(){
+        return Integer.parseInt(getOptional("kylin.snapshot.cache.max.entry", 
"500"));
+    }
+
     public boolean getQueryRunLocalCoprocessor() {
         return 
Boolean.parseBoolean(getOptional("kylin.query.run.local.coprocessor", "false"));
     }

http://git-wip-us.apache.org/repos/asf/kylin/blob/6b45c945/core-dictionary/src/main/java/org/apache/kylin/dict/lookup/SnapshotManager.java
----------------------------------------------------------------------
diff --git 
a/core-dictionary/src/main/java/org/apache/kylin/dict/lookup/SnapshotManager.java
 
b/core-dictionary/src/main/java/org/apache/kylin/dict/lookup/SnapshotManager.java
index 6e93ae4..c7b0d26 100644
--- 
a/core-dictionary/src/main/java/org/apache/kylin/dict/lookup/SnapshotManager.java
+++ 
b/core-dictionary/src/main/java/org/apache/kylin/dict/lookup/SnapshotManager.java
@@ -21,6 +21,8 @@ package org.apache.kylin.dict.lookup;
 import java.io.IOException;
 import java.util.NavigableSet;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.persistence.ResourceStore;
@@ -31,6 +33,12 @@ import org.apache.kylin.source.ReadableTable.TableSignature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+
 /**
  * @author yangli9
  */
@@ -61,33 +69,49 @@ public class SnapshotManager {
     // 
============================================================================
 
     private KylinConfig config;
-    private ConcurrentHashMap<String, SnapshotTable> snapshotCache; // resource
+    private LoadingCache<String, SnapshotTable> snapshotCache; // resource
 
     // path ==>
     // SnapshotTable
 
     private SnapshotManager(KylinConfig config) {
         this.config = config;
-        snapshotCache = new ConcurrentHashMap<String, SnapshotTable>();
+        this.snapshotCache = CacheBuilder.newBuilder().removalListener(new 
RemovalListener<String, SnapshotTable>() {
+            @Override
+            public void onRemoval(RemovalNotification<String, SnapshotTable> 
notification) {
+                SnapshotManager.logger.info("Snapshot with resource path " + 
notification.getKey() + " is removed due to " + notification.getCause());
+            }
+        }).maximumSize(config.getCachedSnapshotMaxEntrySize())//
+                .expireAfterWrite(1, TimeUnit.DAYS).build(new 
CacheLoader<String, SnapshotTable>() {
+                    @Override
+                    public SnapshotTable load(String key) throws Exception {
+                        SnapshotTable snapshotTable = 
SnapshotManager.this.load(key, true);
+                        return snapshotTable;
+                    }
+                });
     }
 
     public void wipeoutCache() {
-        snapshotCache.clear();
+        snapshotCache.invalidateAll();
     }
 
     public SnapshotTable getSnapshotTable(String resourcePath) throws 
IOException {
-        SnapshotTable r = snapshotCache.get(resourcePath);
-        if (r == null) {
-            r = load(resourcePath, true);
-            snapshotCache.put(resourcePath, r);
+        try {
+            SnapshotTable r = snapshotCache.get(resourcePath);
+            if (r == null) {
+                r = load(resourcePath, true);
+                snapshotCache.put(resourcePath, r);
+            }
+            return r;
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e.getCause());
         }
-        return r;
     }
 
     public void removeSnapshot(String resourcePath) throws IOException {
         ResourceStore store = 
MetadataManager.getInstance(this.config).getStore();
         store.deleteResource(resourcePath);
-        snapshotCache.remove(resourcePath);
+        snapshotCache.invalidate(resourcePath);
     }
 
     public SnapshotTable buildSnapshot(ReadableTable table, TableDesc 
tableDesc) throws IOException {

Reply via email to