View Javadoc

    1   /*
    2    * Copyright 2010 Red Hat, Inc.
    3    *
    4    * Red Hat licenses this file to you under the Apache License, version 2.0
    5    * (the "License"); you may not use this file except in compliance with the
    6    * License.  You may obtain a copy of the License at:
    7    *
    8    *    http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.channel.socket.nio;
    17
    18  import java.lang.ref.SoftReference;
    19  import java.nio.ByteBuffer;
    20
    21  /**
    22   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
    23   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
    24   * @version $Rev: 2198 $, $Date: 2010-02-23 09:56:04 +0900 (Tue, 23 Feb 2010) $
    25   */
    26  final class SocketReceiveBufferPool {
    27
    28      private static final int POOL_SIZE = 8;
    29
    30      @SuppressWarnings("unchecked")
    31      private final SoftReference<ByteBuffer>[] pool = new SoftReference[POOL_SIZE];
    32
    33      SocketReceiveBufferPool() {
    34          super();
    35      }
    36
    37      final ByteBuffer acquire(int size) {
    38          final SoftReference<ByteBuffer>[] pool = this.pool;
    39          for (int i = 0; i < POOL_SIZE; i ++) {
    40              SoftReference<ByteBuffer> ref = pool[i];
    41              if (ref == null) {
    42                  continue;
    43              }
    44
    45              ByteBuffer buf = ref.get();
    46              if (buf == null) {
    47                  pool[i] = null;
    48                  continue;
    49              }
    50
    51              if (buf.capacity() < size) {
    52                  continue;
    53              }
    54
    55              pool[i] = null;
    56
    57              buf.clear();
    58              return buf;
    59          }
    60
    61          ByteBuffer buf = ByteBuffer.allocateDirect(normalizeCapacity(size));
    62          buf.clear();
    63          return buf;
    64      }
    65
    66      final void release(ByteBuffer buffer) {
    67          final SoftReference<ByteBuffer>[] pool = this.pool;
    68          for (int i = 0; i < POOL_SIZE; i ++) {
    69              SoftReference<ByteBuffer> ref = pool[i];
    70              if (ref == null || ref.get() == null) {
    71                  pool[i] = new SoftReference<ByteBuffer>(buffer);
    72                  return;
    73              }
    74          }
    75
    76          // pool is full - replace one
    77          final int capacity = buffer.capacity();
    78          for (int i = 0; i< POOL_SIZE; i ++) {
    79              SoftReference<ByteBuffer> ref = pool[i];
    80              ByteBuffer pooled = ref.get();
    81              if (pooled == null) {
    82                  pool[i] = null;
    83                  continue;
    84              }
    85
    86              if (pooled.capacity() < capacity) {
    87                  pool[i] = new SoftReference<ByteBuffer>(buffer);
    88                  return;
    89              }
    90          }
    91      }
    92
    93      private static final int normalizeCapacity(int capacity) {
    94          // Normalize to multiple of 1024
    95          int q = capacity >>> 10;
    96          int r = capacity & 1023;
    97          if (r != 0) {
    98              q ++;
    99          }
    100         return q << 10;
    101     }
    102 }