All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sequoiadb.datasource.AbstractStrategy Maven / Gradle / Ivy

There is a newer version: 5.10
Show newest version
/*
 * Copyright 2018 SequoiaDB Inc.
 *
 * Licensed 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 com.sequoiadb.datasource;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


abstract class AbstractStrategy implements IConnectStrategy {

    protected ArrayDeque _activeConnItemDeque = new ArrayDeque();
    protected ArrayDeque _newlyCreatedConnItemDeque = new ArrayDeque();
    protected ArrayList _addrs = new ArrayList();
    protected Lock _opLock = new ReentrantLock();
    protected Lock _addrLock = new ReentrantLock();

    // we need to keep all the API thread safe
    @Override
    public void init(List addressList, List _idleConnPairs, List _usedConnPairs) {
        // Notice that, we won't depend on the address in used queue, for
        // some addresses may have been removed, but, they may be still in used pool.

        // get addresses to local
        Iterator addrListItr = addressList.iterator();
        while (addrListItr.hasNext()) {
            String addr = addrListItr.next();
            _addAddress(addr);
        }
        // get idle connections information
        if (_idleConnPairs != null) {
            Iterator idleConnPairItr = _idleConnPairs.iterator();
            while (idleConnPairItr.hasNext()) {
                Pair pair = idleConnPairItr.next();
                String addr = pair.first().getAddr();
                _addConnItem(pair.first());
                _addAddress(addr);
            }
        }
    }

    @Override
    public abstract String getAddress();


    @Override
    public ConnItem pollConnItemForGetting() {
        _opLock.lock();
        try {
            // get the youngest one from active deque or get the oldest on from newly created deque
            // for we don't want the newly created connection to be destroy by background cleaning task
            ConnItem connItem = _activeConnItemDeque.pollFirst();
            if (connItem == null) {
                connItem = _newlyCreatedConnItemDeque.pollFirst();
            }
            return connItem;
        } finally {
            _opLock.unlock();
        }
    }

    @Override
    public ConnItem pollConnItemForDeleting() {
        _opLock.lock();
        try {
            // get the oldest one
            ConnItem connItem = _newlyCreatedConnItemDeque.pollFirst();
            if (connItem == null) {
                connItem = _activeConnItemDeque.pollLast();
            }
            return connItem;
        } finally {
            _opLock.unlock();
        }
    }

    @Override
    public ConnItem peekConnItemForDeleting() {
        _opLock.lock();
        try {
            // get the oldest one
            ConnItem connItem = _newlyCreatedConnItemDeque.peekFirst();
            if (connItem == null) {
                connItem = _activeConnItemDeque.peekLast();
            }
            return connItem;
        } finally {
            _opLock.unlock();
        }
    }

    @Override
    public void removeConnItemAfterCleaning(ConnItem connItem) {
        // do nothing
    }

    @Override
    public void updateUsedConnItemCount(ConnItem connItem, int change) {
        // do nothing
    }

    @Override
    public void addAddress(String addr) {
        _addAddress(addr);
    }

    @Override
    public List removeAddress(String addr) {
        List returnList = new ArrayList();
        // remove address
        _addrLock.lock();
        try {
            if (_addrs.contains(addr)) {
                _addrs.remove(addr);
            }
        } finally {
            _addrLock.unlock();
        }
        // remove item
        _opLock.lock();
        try {
            // prepare the return ConnItem for destroying
            Iterator iterator = _activeConnItemDeque.iterator();
            while (iterator.hasNext()) {
                ConnItem connItem = iterator.next();
                if (addr.equals(connItem.getAddr())) {
                    returnList.add(connItem);
                    iterator.remove();
                }
            }
            iterator = _newlyCreatedConnItemDeque.iterator();
            while (iterator.hasNext()) {
                ConnItem connItem = iterator.next();
                if (addr.equals(connItem.getAddr())) {
                    returnList.add(connItem);
                    iterator.remove();
                }
            }
        } finally {
            _opLock.unlock();
        }
        return returnList;
    }

    @Override
    public void addConnItemAfterCreating(ConnItem connItem) {
        _addConnItem(connItem);
    }

    @Override
    public void addConnItemAfterReleasing(ConnItem connItem) {
        _releaseConnItem(connItem);
    }

    private void _addConnItem(ConnItem connItem) {
        _opLock.lock();
        try {
            // all the newly created connections are put to the last of the deque
            _newlyCreatedConnItemDeque.addLast(connItem);
        } finally {
            _opLock.unlock();
        }
    }

    private void _releaseConnItem(ConnItem connItem) {
        _opLock.lock();
        try {
            // all the release connections are put to the header of the deque
            _activeConnItemDeque.addFirst(connItem);
        } finally {
            _opLock.unlock();
        }
    }

    private void _addAddress(String addr) {
        _addrLock.lock();
        try {
            if (!_addrs.contains(addr)) {
                _addrs.add(addr);
            }
        } finally {
            _addrLock.unlock();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy