Package com.taobao.tdhs.jdbc

Source Code of com.taobao.tdhs.jdbc.TDHSClientInstance$ClientKey

/*
* Copyright(C) 2011-2012 Alibaba Group Holding Limited
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License version 2 as
*  published by the Free Software Foundation.
*
*  Authors:
*    wentong <wentong@taobao.com>
*/

package com.taobao.tdhs.jdbc;

import com.taobao.tdhs.client.TDHSClient;
import com.taobao.tdhs.client.TDHSClientImpl;
import com.taobao.tdhs.client.common.TDHSCommon;
import com.taobao.tdhs.client.exception.TDHSException;
import com.taobao.tdhs.jdbc.util.ConvertUtil;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* 管理TDHSClinet实例
*
* @author <a href="mailto:wentong@taobao.com">文通</a>
* @since 12-3-7 上午11:39
*/
public final class TDHSClientInstance {

    private static Logger logger = LoggerFactory.getLogger(TDHSClientInstance.class);

    private static TDHSClientInstance INSTANCE = null;

    /**
     * Method getInstance returns the INSTANCE of this TDHSClientInstance object.
     *
     * @return the INSTANCE (type TDHSClientInstance) of this TDHSClientInstance object.
     */
    public static synchronized TDHSClientInstance getInstance() {
        return INSTANCE != null ? INSTANCE : (INSTANCE = new TDHSClientInstance());
    }

    private final Lock lock = new ReentrantLock();

    private final Map<ClientKey, ClientValue> instances = new ConcurrentHashMap<ClientKey, ClientValue>(10);

    /**
     * Constructor TDHSClientInstance creates a new TDHSClientInstance INSTANCE.
     */
    private TDHSClientInstance() {
    }

    /**
     * Method createConnection ...
     *
     * @param info of type Properties
     *
     * @return ClientKey
     *
     * @throws TDHSException when
     */
    public
    @NotNull
    ClientKey createConnection(@NotNull Properties info) throws TDHSException {
        String host = info.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY, "localhost");
        int port = ConvertUtil.safeConvertInt(info.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY, "9999"), 9999);
        int connectionNumber = ConvertUtil
                .safeConvertInt(info.getProperty(NonRegisteringDriver.CONNECTION_NUMBER_PROPERTY_KEY, "1"), 1);
        int timeOut = ConvertUtil
                .safeConvertInt(info.getProperty(NonRegisteringDriver.TIME_OUT_PROPERTY_KEY, "1000"), 1000);
        boolean needReconnect =
                Boolean.valueOf(info.getProperty(NonRegisteringDriver.NEED_RECONNECT_PROPERTY_KEY, "true"));
        int connectTimeOut = ConvertUtil
                .safeConvertInt(info.getProperty(NonRegisteringDriver.CONNECT_TIMEOUT_PROPERTY_KEY, "1000"), 1000);
        String charsetName = info.getProperty(NonRegisteringDriver.CHARSET_NAME_PROPERTY_KEY);
        String readCode = info.getProperty(NonRegisteringDriver.READ_CODE_PROPERTY_KEY);

        String writeCode = info.getProperty(NonRegisteringDriver.WRITE_CODE_PROPERTY_KEY);
        Boolean lowerCaseTableNames = Boolean.valueOf(info.getProperty(NonRegisteringDriver.LOWER_CASE_TABLE_NAMES
                , "true"));
        TDHSCommon.ProtocolVersion version = TDHSCommon.ProtocolVersion.fromProp(info.getProperty
                (NonRegisteringDriver.VERSION));
        ClientKey key = new ClientKey(new InetSocketAddress(host, port), connectionNumber, timeOut, needReconnect,
                connectTimeOut, charsetName, readCode, writeCode, version);
        logger.debug("createConnection ClientKey:" + key);
        lock.lock();
        try {
            ClientValue value = instances.get(key);
            if (value != null) {
                value.addRefCount();
                key.setClient(value.getClient());
                return key;
            } else {
                TDHSClient tdhsClient =
                        new TDHSClientImpl(key.getAddress(), connectionNumber, timeOut, needReconnect, connectTimeOut,
                                charsetName, readCode, writeCode, lowerCaseTableNames, version);
                value = new ClientValue(tdhsClient);
                instances.put(key, value);
                key.setClient(tdhsClient);
                return key;
            }
        } finally {
            lock.unlock();
        }
    }

    /**
     * Method closeConnection ...
     *
     * @param key of type ClientKey
     */
    public void closeConnection(@NotNull ClientKey key) {
        logger.debug("closeConnection ClientKey:" + key);
        TDHSClient client = null;
        lock.lock();
        try {
            ClientValue value = instances.get(key);
            if (value == null) {
                throw new RuntimeException("Don't have this client in instances,Maybe close twice! key is " + key);
            }
            if (value.needCloseClient()) {
                client = value.getClient();
                instances.remove(key);
            }
        } finally {
            lock.unlock();
        }
        if (client != null) {
            logger.debug("closeConnection and shutDown TDHSClient!");
            client.shutdown();
        }
    }


    private static class ClientValue {
        private TDHSClient client;

        private AtomicLong refCount = new AtomicLong(1);

        private ClientValue(TDHSClient client) {
            this.client = client;
        }

        public TDHSClient getClient() {
            return client;
        }

        private void addRefCount() {
            refCount.incrementAndGet();
        }

        private boolean needCloseClient() {
            return refCount.decrementAndGet() == 0;
        }
    }


    public static class ClientKey {
        private InetSocketAddress address;
        private int connectionNumber;
        private int timeOut;
        private boolean needReconnect;
        private int connectTimeOut;
        private String charsetName;
        private String readCode;
        private String writeCode;
        private TDHSCommon.ProtocolVersion version;

        private TDHSClient client;

        private ClientKey(InetSocketAddress address, int connectionNumber, int timeOut, boolean needReconnect,
                          int connectTimeOut, String charsetName, String readCode, String writeCode,
                          TDHSCommon.ProtocolVersion version) {
            this.address = address;
            this.connectionNumber = connectionNumber;
            this.timeOut = timeOut;
            this.needReconnect = needReconnect;
            this.connectTimeOut = connectTimeOut;
            this.charsetName = charsetName;
            this.readCode = readCode;
            this.writeCode = writeCode;
            this.version = version;
        }

        public TDHSClient getClient() {
            return client;
        }

        public void setClient(TDHSClient client) {
            this.client = client;
        }

        public InetSocketAddress getAddress() {
            return address;
        }

        public int getConnectionNumber() {
            return connectionNumber;
        }

        public int getTimeOut() {
            return timeOut;
        }

        public boolean isNeedReconnect() {
            return needReconnect;
        }

        public int getConnectTimeOut() {
            return connectTimeOut;
        }

        public String getCharsetName() {
            return charsetName;
        }

        public String getReadCode() {
            return readCode;
        }

        public String getWriteCode() {
            return writeCode;
        }

        public TDHSCommon.ProtocolVersion getVersion() {
            return version;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof ClientKey)) return false;

            ClientKey clientKey = (ClientKey) o;

            if (connectTimeOut != clientKey.connectTimeOut) return false;
            if (connectionNumber != clientKey.connectionNumber) return false;
            if (needReconnect != clientKey.needReconnect) return false;
            if (timeOut != clientKey.timeOut) return false;
            if (address != null ? !address.equals(clientKey.address) : clientKey.address != null) return false;
            if (charsetName != null ? !charsetName.equals(clientKey.charsetName) : clientKey.charsetName != null)
                return false;
            if (readCode != null ? !readCode.equals(clientKey.readCode) : clientKey.readCode != null) return false;
            if (writeCode != null ? !writeCode.equals(clientKey.writeCode) : clientKey.writeCode != null) return false;
            if (version != null ? !version.equals(clientKey.version) : clientKey.version != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = address != null ? address.hashCode() : 0;
            result = 31 * result + connectionNumber;
            result = 31 * result + timeOut;
            result = 31 * result + (needReconnect ? 1 : 0);
            result = 31 * result + connectTimeOut;
            result = 31 * result + (charsetName != null ? charsetName.hashCode() : 0);
            result = 31 * result + (readCode != null ? readCode.hashCode() : 0);
            result = 31 * result + (writeCode != null ? writeCode.hashCode() : 0);
            result = 31 * result + (version != null ? version.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "ClientKey{" +
                    "address=" + address +
                    ", connectionNumber=" + connectionNumber +
                    ", timeOut=" + timeOut +
                    ", needReconnect=" + needReconnect +
                    ", connectTimeOut=" + connectTimeOut +
                    ", charsetName='" + charsetName + '\'' +
                    ", readCode='" + readCode + '\'' +
                    ", writeCode='" + writeCode + '\'' +
                    ", version='" + version + '\'' +
                    '}';
        }
    }
}
TOP

Related Classes of com.taobao.tdhs.jdbc.TDHSClientInstance$ClientKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.