View Javadoc

1   /*
2    * Copyright (c) 2010.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.hbql.impl;
22  
23  import org.apache.hadoop.hbase.hbql.client.HBqlException;
24  import org.apache.hadoop.hbase.hbql.util.ArrayBlockingQueues;
25  import org.apache.hadoop.hbase.hbql.util.PoolableElement;
26  
27  import java.util.concurrent.BlockingQueue;
28  import java.util.concurrent.atomic.AtomicInteger;
29  
30  public abstract class ElementPool<T extends PoolableElement> {
31  
32      private final AtomicInteger createdElementCounter = new AtomicInteger(0);
33      private final AtomicInteger takenElementCounter = new AtomicInteger(0);
34      private final BlockingQueue<T> elementPool;
35      private final String name;
36      private final int maxPoolSize;
37  
38      public ElementPool(final String name, final int maxPoolSize) {
39          this.name = name;
40          this.maxPoolSize = maxPoolSize;
41          this.elementPool = ArrayBlockingQueues.newArrayBlockingQueue(this.getMaxPoolSize());
42      }
43  
44      protected abstract T newElement() throws HBqlException;
45  
46      public int getMaxPoolSize() {
47          return this.maxPoolSize;
48      }
49  
50      protected BlockingQueue<T> getElementPool() {
51          return this.elementPool;
52      }
53  
54      public String getName() {
55          return this.name;
56      }
57  
58      private AtomicInteger getCreatedElementCounter() {
59          return this.createdElementCounter;
60      }
61  
62      private AtomicInteger getTakenElementCounter() {
63          return this.takenElementCounter;
64      }
65  
66      public int getCreatedCount() {
67          return this.getCreatedElementCounter().get();
68      }
69  
70      public int getTakenCount() {
71          return this.getTakenElementCounter().get();
72      }
73  
74      protected void addElementToPool() throws HBqlException {
75          if (this.getCreatedElementCounter().get() < this.getMaxPoolSize()) {
76              final T val = this.newElement();
77              this.getElementPool().add(val);
78              this.getCreatedElementCounter().incrementAndGet();
79          }
80      }
81  
82      protected synchronized T take() throws HBqlException {
83  
84          // Grow the pool as necessary, rather than front-loading it.
85          if (this.getElementPool().size() == 0)
86              this.addElementToPool();
87  
88          try {
89              final T retval = this.getElementPool().take();
90              retval.resetElement();
91              this.getTakenElementCounter().incrementAndGet();
92              return retval;
93          }
94          catch (InterruptedException e) {
95              throw new HBqlException("InterruptedException: " + e.getMessage());
96          }
97      }
98  
99      public void release(final T element) {
100         element.resetElement();
101         this.getElementPool().add(element);
102         this.getTakenElementCounter().decrementAndGet();
103     }
104 }