/*
* PacketAllocator.java February 2008
*
* Copyright (C) 2008, Niall Gallagher <niallg@users.sf.net>
*
* 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 org.simpleframework.transport;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
/**
* The <code>PacketAllocator</code> object is used to create packets that
* contain increasing sequence numbers. This acts as a pool for buffers which
* can be recycled by closing the <code>Packet</code> objects created by this
* allocator. As well as creating buffers from a pool of byte buffers this can
* wrap an existing buffer within a packet so it can be used uniformly.
*
* @author Niall Gallagher
*/
class PacketAllocator {
/**
* This is the memory manager used to recycle the buffers.
*/
private final PacketManager manager;
/**
* This is the counter used to generate the sequence numbers.
*/
private final AtomicLong count;
/**
* Constructor for the <code>PacketAllocator</code> object. This is provided
* the size of the buffers that will be allocated and the number of buffers
* that can be lazily created before it will block waiting for the next
* buffer to be returned.
*/
public PacketAllocator() {
this(3);
}
/**
* Constructor for the <code>PacketAllocator</code> object. This is provided
* the size of the buffers that will be allocated and the number of buffers
* that can be lazily created before it will block waiting for the next
* buffer to be returned.
*
* @param allow
* this is the queue size for asynchronous writes
*/
public PacketAllocator(int allow) {
this(allow, 4096);
}
/**
* Constructor for the <code>PacketAllocator</code> object. This is provided
* the size of the buffers that will be allocated and the number of buffers
* that can be lazily created before it will block waiting for the next
* buffer to be returned.
*
* @param allow
* this is the queue size for asynchronous writes
* @param size
* this is the size of the buffers to be allocated
*/
public PacketAllocator(int allow, int size) {
this.manager = new PacketManager(allow, size);
this.count = new AtomicLong();
}
/**
* This creates a <code>Packet</code> from a buffer within the pool of
* buffers. The buffer provided can be modified up until such point as it is
* recycled. To recycle the buffer the packet must be closed, when closed
* the buffer can be reused.
*
* @return this returns a packet backed by a pooled buffer
*/
public Packet allocate() throws PacketException {
long sequence = this.count.getAndIncrement();
ByteBuffer buffer = this.manager.allocate();
return new Appender(buffer, this.manager, sequence);
}
/**
* This creates a <code>Packet</code> by wrapping the provided buffer within
* the packet interface. The buffer provided will be read only such that the
* buffer it wraps is not modified.
*
* @param buffer
* this is the buffer that has been wrapped
*
* @return this returns a packet backed by a pooled buffer
*/
public Packet allocate(ByteBuffer buffer) throws PacketException {
long sequence = this.count.getAndIncrement();
return new Wrapper(buffer, sequence);
}
}