/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.parser; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.FutureTask; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; import com.alipay.zdal.common.SqlType; import com.alipay.zdal.parser.visitor.ZdalSchemaStatVisitor; /** * ���ڻ����������sql�����. * @author xiaoqing.zhouxq * @version $Id: ParserCache.java, v 0.1 2012-5-25 ����03:32:41 xiaoqing.zhouxq Exp $ */ public class ParserCache { private static final ParserCache INSTANCE = new ParserCache(); private ParserCache() { } public static final ParserCache instance() { return INSTANCE; } private final ReentrantLock lock = new ReentrantLock(); private final Map<String, ItemValue> map = new LinkedHashMap<String, ItemValue>(); public int size() { return map.size(); } protected static class ItemValue { /** * ���ݵ�CRUD���� */ private AtomicReference<SqlType> sqlType = new AtomicReference<SqlType>(); /** * ��ȥvirtualTableName���������sql�ֶ� */ private AtomicReference<List<String>> tableNameReplacement = new AtomicReference<List<String>>(); /** * ���������sql */ private AtomicReference<FutureTask<ZdalSchemaStatVisitor>> futureVisitor = new AtomicReference<FutureTask<ZdalSchemaStatVisitor>>(); public SqlType getSqlType() { return sqlType.get(); } public SqlType setSqlTypeIfAbsent(SqlType sqlTypeinput) { //���ԭֵΪnull���ԭ�ӵ�������ֵ��ȥ�����ҷ�����ֵ if (sqlType.compareAndSet(null, sqlTypeinput)) { return sqlTypeinput; } else { //��������ֵ�Ѿ���Ϊnull�����ȡ��ֵ return sqlType.get(); } } public List<String> getTableNameReplacement() { return tableNameReplacement.get(); } public List<String> setTableNameReplacementIfAbsent(List<String> tableNameReplacementList) { //���ԭֵΪnull���ԭ�ӵ�������ֵ��ȥ�����ҷ�����ֵ if (tableNameReplacement.compareAndSet(null, tableNameReplacementList)) { return tableNameReplacementList; } else { //��������ֵ�Ѿ���Ϊnull�����ȡ��ֵ return tableNameReplacement.get(); } } public FutureTask<ZdalSchemaStatVisitor> getFutureVisitor() { return futureVisitor.get(); } public FutureTask<ZdalSchemaStatVisitor> setFutureVisitorIfAbsent(FutureTask<ZdalSchemaStatVisitor> future) { //���ԭֵΪnull���ԭ�ӵ�������ֵ��ȥ�����ҷ�����ֵ if (futureVisitor.compareAndSet(null, future)) { return future; } else { //��������ֵ�Ѿ���Ϊnull�����ȡ��ֵ return futureVisitor.get(); } } } protected ItemValue get(String sql) { return map.get(sql); } public SqlType getSqlType(String sql) { ItemValue itemValue = get(sql); if (itemValue != null) { return itemValue.getSqlType(); } else { return null; } } public SqlType setSqlTypeIfAbsent(String sql, SqlType sqlType) { ItemValue itemValue = get(sql); SqlType returnSqlType = null; if (itemValue == null) { //��ȫû�е����������������£��϶�����Ϊ��û���߳����������ij��sql lock.lock(); try { // ˫���lock itemValue = get(sql); if (itemValue == null) { itemValue = new ParserCache.ItemValue(); put(sql, itemValue); } } finally { lock.unlock(); } //cas ����ItemValue�е�SqlType���� returnSqlType = itemValue.setSqlTypeIfAbsent(sqlType); } else if (itemValue.getFutureVisitor() == null) { //cas ����ItemValue�е�SqlType���� returnSqlType = itemValue.setSqlTypeIfAbsent(sqlType); } else { returnSqlType = itemValue.getSqlType(); } return returnSqlType; } public FutureTask<ZdalSchemaStatVisitor> getFutureTask(String sql) { ItemValue itemValue = get(sql); if (itemValue != null) { return itemValue.getFutureVisitor(); } else { return null; } } public List<String> getTableNameReplacement(String sql) { ItemValue itemValue = get(sql); if (itemValue != null) { return itemValue.getTableNameReplacement(); } else { return null; } } public List<String> setTableNameReplacementIfAbsent(String sql, List<String> tablenameReplacement) { ItemValue itemValue = get(sql); List<String> returnList = null; if (itemValue == null) { //��ȫû�е����������������£��϶�����Ϊ��û���ֳ����������ij��sql lock.lock(); try { // ˫���lock itemValue = get(sql); if (itemValue == null) { itemValue = new ParserCache.ItemValue(); put(sql, itemValue); } } finally { lock.unlock(); } //cas ����ItemValue�е�TableNameReplacement���� returnList = itemValue.setTableNameReplacementIfAbsent(tablenameReplacement); } else if (itemValue.getTableNameReplacement() == null) { //cas ����ItemValue�е�TableNameReplacement���� returnList = itemValue.setTableNameReplacementIfAbsent(tablenameReplacement); } else { returnList = itemValue.getTableNameReplacement(); } return returnList; } public FutureTask<ZdalSchemaStatVisitor> setFutureTaskIfAbsent(String sql, FutureTask<ZdalSchemaStatVisitor> future) { ItemValue itemValue = get(sql); FutureTask<ZdalSchemaStatVisitor> returnFutureTask = null; if (itemValue == null) { //��ȫû�е����������������£��϶�����Ϊ��û���ֳ����������ij��sql lock.lock(); try { // ˫���lock itemValue = get(sql); if (itemValue == null) { itemValue = new ParserCache.ItemValue(); put(sql, itemValue); } } finally { lock.unlock(); } //cas ����ItemValue�е�Visitor���� returnFutureTask = itemValue.setFutureVisitorIfAbsent(future); } else if (itemValue.getFutureVisitor() == null) { //cas ����ItemValue�е�Visitor���� returnFutureTask = itemValue.setFutureVisitorIfAbsent(future); } else { returnFutureTask = itemValue.getFutureVisitor(); } return returnFutureTask; } protected void put(String sql, ItemValue itemValue) { map.put(sql, itemValue); } }