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

com.aerospike.client.cluster.Pool Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012-2021 Aerospike, Inc.
 *
 * Portions may be licensed to Aerospike, Inc. under one or more contributor
 * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
 *
 * 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.aerospike.client.cluster;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Concurrent bounded LIFO stack of connections.
 * 

* The standard library concurrent stack, ConcurrentLinkedDequeue, will not suffice * because it's not bounded and it's size() method is too expensive. */ public final class Pool { private final Connection[] conns; private int head; private int tail; private int size; final int minSize; private final ReentrantLock lock; final AtomicInteger total; // total connections: inUse + inPool public Pool(int minSize, int maxSize) { this.minSize = minSize; conns = new Connection[maxSize]; lock = new ReentrantLock(false); total = new AtomicInteger(); } public int capacity() { return conns.length; } /** * Return number of connections that might be closed. */ public int excess() { return total.get() - minSize; } /** * Insert connection at head of stack. */ public boolean offer(Connection conn) { if (conn == null) { throw new NullPointerException(); } final ReentrantLock lock = this.lock; lock.lock(); try { if (size == conns.length) { return false; } final Connection[] conns = this.conns; conns[head] = conn; if (++head == conns.length) { head = 0; } size++; return true; } finally { lock.unlock(); } } /** * Pop connection from head of stack. */ public Connection poll() { final ReentrantLock lock = this.lock; lock.lock(); try { if (size == 0) { return null; } if (head == 0) { head = conns.length - 1; } else { head--; } size--; final Connection[] conns = this.conns; final Connection conn = conns[head]; conns[head] = null; return conn; } finally { lock.unlock(); } } /** * Close connections that are idle for more than maxSocketIdle up to count. */ void closeIdle(Node node, int count) { final Cluster cluster = node.cluster; while (count > 0) { // Lock on each iteration to give fairness to other // threads polling for connections. Connection conn; final ReentrantLock lock = this.lock; lock.lock(); try { if (size == 0) { return; } // The oldest connection is at tail. final Connection[] conns = this.conns; conn = conns[tail]; if (cluster.isConnCurrentTrim(conn.getLastUsed())) { return; } conns[tail] = null; if (++tail == conns.length) { tail = 0; } size--; } finally { lock.unlock(); } // Close connection outside of lock. closeIdle(node, conn); count--; } } void closeIdle(Node node, Connection conn) { total.getAndDecrement(); node.closeIdleConnection(conn); } /** * Return item count. */ public int size() { final ReentrantLock lock = this.lock; lock.lock(); try { return size; } finally { lock.unlock(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy