package com.taobao.tddl.optimizer.costbased.esitimater.stat; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.taobao.tddl.common.exception.NotSupportException; import com.taobao.tddl.common.exception.TddlException; import com.taobao.tddl.common.model.Group; import com.taobao.tddl.common.model.lifecycle.AbstractLifecycle; import com.taobao.tddl.common.utils.extension.ExtensionLoader; import com.taobao.tddl.optimizer.exceptions.OptimizerException; /** * 基于repo的{@linkplain StatManager}的委托实现 * * @author jianghang 2013-12-6 下午3:41:29 * @since 5.0.0 */ public class RepoStatManager extends AbstractLifecycle implements StatManager { private static TableStat nullTableStat = new TableStat(); private static KVIndexStat nullKVIndexStat = new KVIndexStat(); private RepoStatManager delegate; private boolean isDelegate; private Group group; private LocalStatManager local; private LoadingCache<String, KVIndexStat> kvIndexCache = null; private LoadingCache<String, TableStat> tableCache = null; private boolean useCache; protected void doInit() throws TddlException { if (!isDelegate) { delegate = ExtensionLoader.load(RepoStatManager.class, group.getType().name()); delegate.setGroup(group); delegate.setDelegate(true); delegate.init(); kvIndexCache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(30000, TimeUnit.MILLISECONDS) .build(new CacheLoader<String, KVIndexStat>() { public KVIndexStat load(String tableName) throws Exception { KVIndexStat result = delegate.getKVIndex0(tableName); if (result == null) { result = nullKVIndexStat; } return result; } }); tableCache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(30000, TimeUnit.MILLISECONDS) .build(new CacheLoader<String, TableStat>() { public TableStat load(String tableName) throws Exception { TableStat result = delegate.getTable0(tableName); if (result == null) { result = nullTableStat; } return result; } }); } if (local != null && !local.isInited()) { local.init(); } } protected void doDestory() throws TddlException { super.doDestory(); if (local != null && local.isInited()) { local.destory(); } if (!isDelegate) { delegate.destory(); kvIndexCache.cleanUp(); tableCache.cleanUp(); } } public KVIndexStat getKVIndex(String indexName) { KVIndexStat stat = null; if (local != null) {// 本地如果开启了,先找本地 stat = local.getKVIndex(indexName); } if (stat == null) { if (useCache) { try { stat = kvIndexCache.get(indexName); if (stat == nullKVIndexStat) { return null; } } catch (ExecutionException e) { throw new OptimizerException(e); } } else { return delegate.getKVIndex0(indexName); } } return stat; } public TableStat getTable(String tableName) { TableStat stat = null; if (local != null) {// 本地如果开启了,先找本地 stat = local.getTable(tableName); } if (stat == null) { if (useCache) { try { stat = tableCache.get(tableName); if (stat == nullTableStat) { return null; } } catch (ExecutionException e) { throw new OptimizerException(e); } } else { return delegate.getTable0(tableName); } } return stat; } protected KVIndexStat getKVIndex0(String indexName) { throw new NotSupportException("对应repo需要实现"); } protected TableStat getTable0(String tableName) { throw new NotSupportException("对应repo需要实现"); } public void setDelegate(boolean isDelegate) { this.isDelegate = isDelegate; } public void setGroup(Group group) { this.group = group; } public void setUseCache(boolean useCache) { this.useCache = useCache; } public void setLocal(LocalStatManager local) { this.local = local; } }