Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   * Copyright 2014 Red Hat, Inc., and individual contributors
   * as indicated by the @author tags.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 
 package io.undertow.server.handlers.cache;
 
 
A limited buffer pooled allocator. This pool uses a series of buffer regions to back the returned pooled buffers. When the buffer is no longer needed, it should be freed back into the pool; failure to do so will cause the corresponding buffer area to be unavailable until the buffer is garbage-collected.

Author(s):
David M. Lloyd
Jason T. Greene
 
 public final class LimitedBufferSlicePool {
 
     private static final AtomicIntegerFieldUpdater regionUpdater = AtomicIntegerFieldUpdater.newUpdater(LimitedBufferSlicePool.class"regionsUsed");
     private final Queue<SlicesliceQueue = new ConcurrentLinkedQueue<>();
     private final BufferAllocator<ByteBufferallocator;
     private final int bufferSize;
     private final int buffersPerRegion;
     private final int maxRegions;
     private volatile int regionsUsed;


    
Construct a new instance.

Parameters:
allocator the buffer allocator to use
bufferSize the size of each buffer
maxRegionSize the maximum region size for each backing buffer
maxRegions the maximum regions to create, zero for unlimited
 
     public LimitedBufferSlicePool(final BufferAllocator<ByteBufferallocatorfinal int bufferSizefinal int maxRegionSizefinal int maxRegions) {
         if (bufferSize <= 0) {
             throw new IllegalArgumentException("Buffer size must be greater than zero");
         }
         if (maxRegionSize < bufferSize) {
             throw new IllegalArgumentException("Maximum region size must be greater than or equal to the buffer size");
         }
          = maxRegionSize / bufferSize;
         this. = bufferSize;
         this. = allocator;
         this. = maxRegions;
     }

     
Construct a new instance.

Parameters:
allocator the buffer allocator to use
bufferSize the size of each buffer
maxRegionSize the maximum region size for each backing buffer
 
     public LimitedBufferSlicePool(BufferAllocator<ByteBufferallocatorint bufferSizeint maxRegionSize) {
         this(allocatorbufferSizemaxRegionSize, 0);
     }


    
Construct a new instance, using a direct buffer allocator.

Parameters:
bufferSize the size of each buffer
maxRegionSize the maximum region size for each backing buffer
 
     public LimitedBufferSlicePool(final int bufferSizefinal int maxRegionSize) {
         this(.bufferSizemaxRegionSize);
     }

    
Allocates a new byte buffer if possible

Returns:
new buffer or null if none available
 
     public PooledByteBuffer allocate() {
         final Queue<SlicesliceQueue = this.;
        final Slice slice = sliceQueue.poll();
        if (slice == null && ( <= 0 || .getAndIncrement(this) < )) {
            final int bufferSize = this.;
            final int buffersPerRegion = this.;
            final ByteBuffer region = .allocate(buffersPerRegion * bufferSize);
            int idx = bufferSize;
            for (int i = 1; i < buffersPerRegioni ++) {
                sliceQueue.add(new Slice(regionidxbufferSize));
                idx += bufferSize;
            }
            final Slice newSlice = new Slice(region, 0, bufferSize);
            return new PooledByteBuffer(newSlicenewSlice.slice(), sliceQueue);
        }
        if (slice == null) {
            return null;
        }
        return new PooledByteBuffer(sliceslice.slice(), sliceQueue);
    }
    public boolean canAllocate(int slices) {
        if ( < )
            return true;
        if (.isEmpty())
            return false;
        Iterator iterator = .iterator();
        for (int i = 0; i < slicesi++) {
            if (! iterator.hasNext()) {
                return false;
            }
            try {
                iterator.next();
            } catch (NoSuchElementException e) {
                return false;
            }
        }
        return true;
    }
    public static final class PooledByteBuffer {
        private final Slice region;
        private final Queue<Sliceslices;
        volatile ByteBuffer buffer;
        private static final AtomicReferenceFieldUpdater<PooledByteBufferByteBufferbufferUpdater = AtomicReferenceFieldUpdater.newUpdater(PooledByteBuffer.classByteBuffer.class"buffer");
        private PooledByteBuffer(final Slice regionfinal ByteBuffer bufferfinal Queue<Sliceslices) {
            this. = region;
            this. = buffer;
            this. = slices;
        }
        public void free() {
            if (.getAndSet(thisnull) != null) {
                // trust the user, repool the buffer
                .add();
            }
        }
        public ByteBuffer getResource() {
            final ByteBuffer buffer = this.;
            if (buffer == null) {
                throw new IllegalStateException();
            }
            return buffer;
        }
        public String toString() {
            return "Pooled buffer " + ;
        }
    }
    private final class Slice {
        private final ByteBuffer parent;
        private final int start;
        private final int size;
        private Slice(final ByteBuffer parentfinal int startfinal int size) {
            this. = parent;
            this. = start;
            this. = size;
        }
        ByteBuffer slice() {
            return ((ByteBuffer).duplicate().position().limit(+)).slice();
        }
    }
New to GrepCode? Check out our FAQ X