View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the 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.nio.ByteBuffer;
    19
    20  import org.jboss.netty.util.internal.ByteBufferUtil;
    21
    22  final class SocketReceiveBufferAllocator {
    23
    24      private ByteBuffer buf;
    25      private int exceedCount;
    26      private final int maxExceedCount;
    27      private final int percentual;
    28
    29      SocketReceiveBufferAllocator() {
    30          this(16, 80);
    31      }
    32
    33      SocketReceiveBufferAllocator(int maxExceedCount, int percentual) {
    34          this.maxExceedCount = maxExceedCount;
    35          this.percentual = percentual;
    36      }
    37
    38
    39      ByteBuffer get(int size) {
    40          if (buf == null) {
    41              return newBuffer(size);
    42          } else if (buf.capacity() < size) {
    43              return newBuffer(size);
    44          } else if (((buf.capacity() / 100) * percentual) > size) {
    45              if (++exceedCount == maxExceedCount) {
    46                 return newBuffer(size);
    47              } else {
    48                  buf.clear();
    49              }
    50          } else {
    51              exceedCount = 0;
    52              buf.clear();
    53          }
    54          return buf;
    55      }
    56
    57      private ByteBuffer newBuffer(int size) {
    58          if (buf != null) {
    59              exceedCount = 0;
    60              ByteBufferUtil.destroy(buf);
    61          }
    62          buf = ByteBuffer.allocateDirect(normalizeCapacity(size));
    63          return buf;
    64      }
    65
    66      private static int normalizeCapacity(int capacity) {
    67          // Normalize to multiple of 1024
    68          int q = capacity >>> 10;
    69          int r = capacity & 1023;
    70          if (r != 0) {
    71              q ++;
    72          }
    73          return q << 10;
    74      }
    75  }