feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
254
jdkSrc/jdk8/com/sun/jndi/ldap/pool/Pool.java
Normal file
254
jdkSrc/jdk8/com/sun/jndi/ldap/pool/Pool.java
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.ldap.pool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* A map of pool ids to Connections.
|
||||
* Key is an object that uniquely identifies a PooledConnection request
|
||||
* (typically information needed to create the connection).
|
||||
* The definitions of the key's equals() and hashCode() methods are
|
||||
* vital to its unique identification in a Pool.
|
||||
*
|
||||
* Value is a ConnectionsRef, which is a reference to Connections,
|
||||
* a list of equivalent connections.
|
||||
*
|
||||
* Supports methods that
|
||||
* - retrieves (or creates as necessary) a connection from the pool
|
||||
* - removes expired connections from the pool
|
||||
*
|
||||
* Connections cleanup:
|
||||
* A WeakHashMap is used for mapping the pool ids and Connections.
|
||||
* A SoftReference from the value to the key is kept to hold the map
|
||||
* entry as long as possible. This allows the GC to remove Connections
|
||||
* from the Pool under situations of VM running out of resources.
|
||||
* To take an appropriate action of 'closing the connections' before the GC
|
||||
* reclaims the ConnectionsRef objects, the ConnectionsRef objects are made
|
||||
* weakly reachable through a list of weak references registered with
|
||||
* a reference queue.
|
||||
* Upon an entry gets removed from the WeakHashMap, the ConnectionsRef (value
|
||||
* in the map) object is weakly reachable. When another sweep of
|
||||
* clearing the weak references is made by the GC it puts the corresponding
|
||||
* ConnectionsWeakRef object into the reference queue.
|
||||
* The reference queue is monitored lazily for reclaimable Connections
|
||||
* whenever a pooled connection is requested or a call to remove the expired
|
||||
* connections is made. The monitoring is done regularly when idle connection
|
||||
* timeout is set as the PoolCleaner removes expired connections periodically.
|
||||
* As determined by the experiements, cleanup of resources using the
|
||||
* ReferenceQueue mechanism is reliable and has immidiate effect than the
|
||||
* finalizer approach.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
final public class Pool {
|
||||
|
||||
static final boolean debug = com.sun.jndi.ldap.LdapPoolManager.debug;
|
||||
|
||||
/*
|
||||
* Used for connections cleanup
|
||||
*/
|
||||
private static final ReferenceQueue<ConnectionsRef> queue =
|
||||
new ReferenceQueue<>();
|
||||
private static final Collection<Reference<ConnectionsRef>> weakRefs =
|
||||
Collections.synchronizedList(new LinkedList<Reference<ConnectionsRef>>());
|
||||
|
||||
final private int maxSize; // max num of identical conn per pool
|
||||
final private int prefSize; // preferred num of identical conn per pool
|
||||
final private int initSize; // initial number of identical conn to create
|
||||
final private Map<Object, ConnectionsRef> map;
|
||||
|
||||
public Pool(int initSize, int prefSize, int maxSize) {
|
||||
map = new WeakHashMap<>();
|
||||
this.prefSize = prefSize;
|
||||
this.maxSize = maxSize;
|
||||
this.initSize = initSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pooled connection for id. The pooled connection might be
|
||||
* newly created, as governed by the maxSize and prefSize settings.
|
||||
* If a pooled connection is unavailable and cannot be created due
|
||||
* to the maxSize constraint, this call blocks until the constraint
|
||||
* is removed or until 'timeout' ms has elapsed.
|
||||
*
|
||||
* @param id identity of the connection to get
|
||||
* @param timeout the number of milliseconds to wait before giving up
|
||||
* @param factory the factory to use for creating the connection if
|
||||
* creation is necessary
|
||||
* @return a pooled connection
|
||||
* @throws NamingException the connection could not be created due to
|
||||
* an error.
|
||||
*/
|
||||
public PooledConnection getPooledConnection(Object id, long timeout,
|
||||
PooledConnectionFactory factory) throws NamingException {
|
||||
|
||||
d("get(): ", id);
|
||||
if (debug) {
|
||||
synchronized (map) {
|
||||
d("size: ", map.size());
|
||||
}
|
||||
}
|
||||
|
||||
expungeStaleConnections();
|
||||
|
||||
Connections conns;
|
||||
synchronized (map) {
|
||||
conns = getConnections(id);
|
||||
if (conns == null) {
|
||||
d("get(): creating new connections list for ", id);
|
||||
|
||||
// No connections for this id so create a new list
|
||||
conns = new Connections(id, initSize, prefSize, maxSize,
|
||||
factory);
|
||||
ConnectionsRef connsRef = new ConnectionsRef(conns);
|
||||
map.put(id, connsRef);
|
||||
|
||||
// Create a weak reference to ConnectionsRef
|
||||
Reference<ConnectionsRef> weakRef =
|
||||
new ConnectionsWeakRef(connsRef, queue);
|
||||
|
||||
// Keep the weak reference through the element of a linked list
|
||||
weakRefs.add(weakRef);
|
||||
}
|
||||
d("get(): size after: ", map.size());
|
||||
}
|
||||
|
||||
return conns.get(timeout, factory); // get one connection from list
|
||||
}
|
||||
|
||||
private Connections getConnections(Object id) {
|
||||
ConnectionsRef ref = map.get(id);
|
||||
return (ref != null) ? ref.getConnections() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes through the connections in this Pool and expires ones that
|
||||
* have been idle before 'threshold'. An expired connection is closed
|
||||
* and then removed from the pool (removePooledConnection() will eventually
|
||||
* be called, and the list of pools itself removed if it becomes empty).
|
||||
*
|
||||
* @param threshold connections idle before 'threshold' should be closed
|
||||
* and removed.
|
||||
*/
|
||||
public void expire(long threshold) {
|
||||
Collection<ConnectionsRef> copy;
|
||||
synchronized (map) {
|
||||
copy = new ArrayList<>(map.values());
|
||||
}
|
||||
|
||||
ArrayList<ConnectionsRef> removed = new ArrayList<>();
|
||||
Connections conns;
|
||||
for (ConnectionsRef ref : copy) {
|
||||
conns = ref.getConnections();
|
||||
if (conns.expire(threshold)) {
|
||||
d("expire(): removing ", conns);
|
||||
removed.add(ref);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (map) {
|
||||
map.values().removeAll(removed);
|
||||
}
|
||||
|
||||
expungeStaleConnections();
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes the connections contained in the ConnectionsRef object that
|
||||
* is going to be reclaimed by the GC. Called by getPooledConnection()
|
||||
* and expire() methods of this class.
|
||||
*/
|
||||
private static void expungeStaleConnections() {
|
||||
ConnectionsWeakRef releaseRef = null;
|
||||
while ((releaseRef = (ConnectionsWeakRef) queue.poll())
|
||||
!= null) {
|
||||
Connections conns = releaseRef.getConnections();
|
||||
|
||||
if (debug) {
|
||||
System.err.println(
|
||||
"weak reference cleanup: Closing Connections:" + conns);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
conns.close();
|
||||
weakRefs.remove(releaseRef);
|
||||
releaseRef.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showStats(PrintStream out) {
|
||||
Object id;
|
||||
Connections conns;
|
||||
|
||||
out.println("===== Pool start ======================");
|
||||
out.println("maximum pool size: " + maxSize);
|
||||
out.println("preferred pool size: " + prefSize);
|
||||
out.println("initial pool size: " + initSize);
|
||||
|
||||
synchronized (map) {
|
||||
out.println("current pool size: " + map.size());
|
||||
|
||||
for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) {
|
||||
id = entry.getKey();
|
||||
conns = entry.getValue().getConnections();
|
||||
out.println(" " + id + ":" + conns.getStats());
|
||||
}
|
||||
}
|
||||
|
||||
out.println("====== Pool end =====================");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
synchronized (map) {
|
||||
return super.toString() + " " + map.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void d(String msg, int i) {
|
||||
if (debug) {
|
||||
System.err.println(this + "." + msg + i);
|
||||
}
|
||||
}
|
||||
|
||||
private void d(String msg, Object obj) {
|
||||
if (debug) {
|
||||
System.err.println(this + "." + msg + obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user