1010 */
1111final class FreeConnectionBuffer {
1212
13- /**
14- * Buffer oriented for add and remove.
15- */
16- private final LinkedList < PooledConnection > freeBuffer = new LinkedList <>() ;
13+
14+ private final Node free = Node . init ();
15+
16+ int size = 0 ;
1717
1818 /**
1919 * Return the number of entries in the buffer.
2020 */
2121 int size () {
22- return freeBuffer . size () ;
22+ return size ;
2323 }
2424
2525 /**
2626 * Return true if the buffer is empty.
2727 */
2828 boolean isEmpty () {
29- return freeBuffer . isEmpty () ;
29+ return size == 0 ;
3030 }
3131
3232 /**
3333 * Add connection to the free list.
3434 */
3535 void add (PooledConnection pc ) {
36- freeBuffer .addFirst (pc );
36+ new Node (pc ).addAfter (free );
37+ size ++;
3738 }
3839
3940 /**
4041 * Remove a connection from the free list.
4142 */
4243 PooledConnection remove () {
43- return freeBuffer .removeFirst ();
44+ Node node = free .next ;
45+ node .remove ();
46+ size --;
47+ return node .pc ;
4448 }
4549
4650 /**
4751 * Close all connections in this buffer.
4852 */
4953 void closeAll (boolean logErrors ) {
50- List <PooledConnection > tempList = new ArrayList <>(freeBuffer );
51- freeBuffer .clear ();
54+ List <PooledConnection > tempList = new ArrayList <>();
55+ while (size > 0 ) {
56+ tempList .add (remove ());
57+ }
58+
5259 if (Log .isLoggable (System .Logger .Level .TRACE )) {
5360 Log .trace ("... closing all {0} connections from the free list with logErrors: {1}" , tempList .size (), logErrors );
5461 }
@@ -62,15 +69,82 @@ void closeAll(boolean logErrors) {
6269 */
6370 int trim (int minSize , long usedSince , long createdSince ) {
6471 int trimCount = 0 ;
65- ListIterator <PooledConnection > iterator = freeBuffer .listIterator (minSize );
66- while (iterator .hasNext ()) {
67- PooledConnection pooledConnection = iterator .next ();
68- if (pooledConnection .shouldTrim (usedSince , createdSince )) {
69- iterator .remove ();
70- pooledConnection .closeConnectionFully (true );
72+ Node node = free ; // first boundary node
73+ do {
74+ node = node .next ;
75+ } while (!node .isBoundaryNode () && minSize -- > 0 );
76+
77+ while (!node .isBoundaryNode ()) {
78+ Node current = node ;
79+ node = node .next ;
80+ if (current .pc .shouldTrim (usedSince , createdSince )) {
81+ current .remove ();
82+ size --;
83+ current .pc .closeConnectionFully (true );
7184 trimCount ++;
7285 }
7386 }
7487 return trimCount ;
7588 }
89+
90+ /**
91+ * Node of a linkedlist. The linkedLists always have two empty nodes at the start and end.
92+ * (boundary nodes) They are generated with the init() method.
93+ * <p>
94+ * the first usable node is startNode.next (which could be the end edge)
95+ */
96+ static final class Node {
97+
98+ private Node next ;
99+ private Node prev ;
100+ final PooledConnection pc ;
101+
102+ private Node (PooledConnection pc ) {
103+ this .pc = pc ;
104+ }
105+
106+ /**
107+ * Creates new "list" with two empty boundary nodes
108+ */
109+ public static Node init () {
110+ Node node1 = new Node (null );
111+ Node node2 = new Node (null );
112+ node1 .next = node2 ;
113+ node2 .prev = node1 ;
114+ return node1 ;
115+ }
116+
117+ /**
118+ * Retruns true, if this is a boundary node. (start or end node of list)
119+ */
120+ private boolean isBoundaryNode () {
121+ return pc == null ;
122+ }
123+
124+ /**
125+ * Removes the node from the list. The node can be re-added to an other list
126+ */
127+ private void remove () {
128+ assert pc != null : "called remove a boundary node" ;
129+ assert prev != null && next != null : "not part of a list" ;
130+ next .prev = prev ;
131+ prev .next = next ;
132+ prev = null ;
133+ next = null ;
134+ }
135+
136+ /**
137+ * Adds <code>this</code> after <code>node</code>.
138+ * <p>
139+ * Node is in most cases a boundary node (e.g. start of list)
140+ */
141+ public void addAfter (Node node ) {
142+ assert !this .isBoundaryNode () : "this is a boundary node" ;
143+ assert next == null & prev == null : "Node already member of a list" ;
144+ next = node .next ;
145+ prev = node ;
146+ node .next .prev = this ;
147+ node .next = this ;
148+ }
149+ }
76150}
0 commit comments