You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MpLive/library/src/main/java/net/ossrs/yasea/SrsAllocator.java

117 lines
3.3 KiB
Java

package net.ossrs.yasea;
import java.util.Arrays;
public final class SrsAllocator {
public class Allocation {
private byte[] data;
private int size;
public Allocation(int size) {
this.data = new byte[size];
this.size = 0;
}
public byte[] array() {
return data;
}
public int size() {
return size;
}
public void appendOffset(int offset) {
size += offset;
}
public void clear() {
size = 0;
}
public void put(byte b) {
data[size++] = b;
}
public void put(byte b, int pos) {
data[pos++] = b;
size = pos > size ? pos : size;
}
public void put(short s) {
put((byte) s);
put((byte) (s >>> 8));
}
public void put(int i) {
put((byte) i);
put((byte) (i >>> 8));
put((byte) (i >>> 16));
put((byte) (i >>> 24));
}
public void put(byte[] bs) {
System.arraycopy(bs, 0, data, size, bs.length);
size += bs.length;
}
}
private final int individualAllocationSize;
private volatile int availableSentinel;
private Allocation[] availableAllocations;
/**
* Constructs an instance without creating any {@link Allocation}s up front.
*
* @param individualAllocationSize The length of each individual {@link Allocation}.
*/
public SrsAllocator(int individualAllocationSize) {
this(individualAllocationSize, 0);
}
/**
* Constructs an instance with some {@link Allocation}s created up front.
* <p>
*
* @param individualAllocationSize The length of each individual {@link Allocation}.
* @param initialAllocationCount The number of allocations to create up front.
*/
public SrsAllocator(int individualAllocationSize, int initialAllocationCount) {
this.individualAllocationSize = individualAllocationSize;
this.availableSentinel = initialAllocationCount + 10;
this.availableAllocations = new Allocation[availableSentinel];
for (int i = 0; i < availableSentinel; i++) {
availableAllocations[i] = new Allocation(individualAllocationSize);
}
}
public synchronized Allocation allocate(int size) {
for (int i = 0; i < availableSentinel; i++) {
if (availableAllocations[i].size() >= size) {
Allocation ret = availableAllocations[i];
availableAllocations[i] = null;
return ret;
}
}
return new Allocation(size > individualAllocationSize ? size : individualAllocationSize);
}
public synchronized void release(Allocation allocation) {
allocation.clear();
for (int i = 0; i < availableSentinel; i++) {
if (availableAllocations[i].size() == 0) {
availableAllocations[i] = allocation;
return;
}
}
if (availableSentinel + 1 > availableAllocations.length) {
availableAllocations = Arrays.copyOf(availableAllocations, availableAllocations.length * 2);
}
availableAllocations[availableSentinel++] = allocation;
}
}