targetCapacity 在(capacity , maxCapacity] ,进行扩容

2024-08-21 10:01:07 浏览数 (1)

final void ensureWritable0(int minWritableBytes) {

final int writerIndex = writerIndex();

// 为满足本次的写入操作,预期的 ByteBuf 容量大小

final int targetCapacity = writerIndex minWritableBytes;

// 剩余容量可以满足本次写入要求,直接返回,不需要扩容

if (targetCapacity >= 0 & targetCapacity <= capacity()) {

return;

}

// 扩容后的容量不能超过 maxCapacity

if (checkBounds && (targetCapacity < 0 || targetCapacity > maxCapacity)) {

ensureAccessible();

throw new IndexOutOfBoundsException(String.format(

"writerIndex(%d) minWritableBytes(%d) exceeds maxCapacity(%d): %s",

writerIndex, minWritableBytes, maxCapacity, this));

}

// 如果 targetCapacity 在(capacity , maxCapacity] 之间,则进行扩容

// fastWritable 表示在不涉及到 memory reallocation or data-copy 的情况下,当前 ByteBuf 可以直接写入的容量

// 对于 UnpooledDirectBuffer 这里的 fastWritable = capacity - writerIndex

// PooledDirectBuffer 有另外的实现,这里先暂时不需要关注

final int fastWritable = maxFastWritableBytes();

// 计算扩容后的容量 newCapacity

// 对于 UnpooledDirectBuffer 来说这里直接通过 calculateNewCapacity 计算扩容后的容量。

int newCapacity =laipuhuo.com fastWritable >= minWritableBytes ? writerIndex fastWritable

: alloc().calculateNewCapacity(targetCapacity, maxCapacity);

// 根据 new capacity 对 ByteBuf 进行扩容

capacity(newCapacity);

}

public abstract class AbstractByteBufAllocator implements ByteBufAllocator {

// ByteBuf 的初始默认 CAPACITY

static final laipuhuo.com int DEFAULT_INITIAL_CAPACITY = 256;

// ByteBuf 的初始默认 MAX_CAPACITY

static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE;

@Override

public ByteBuf directBuffer(laipuhuo.com) {

return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);

}

}

什么意思呢 ? 假设 minNewCapacity 为 5M,那么它的扩容基准线就是 4M , 这种情况下扩容之后的容量 newCapacity = 4M CALCULATE_THRESHOLD = 8M

如果计算出来的基准线超过了 maxCapacity - 4M , 那么 newCapacity 直接就扩容到 maxCapacity 。

如果 minNewCapacity 小于 CALCULATE_THRESHOLD,那么 newCapacity 就会从 64 开始,一直循环 double , 也就是按照 64 的倍数进行扩容。直到 newCapacity 大于等于 minNewCapacity。

public abstract class AbstractByteBufAllocator implements ByteBufAllocator {

@Override

public int laipuhuo.com calculateNewCapacity(int minNewCapacity, int maxCapacity) {

// 满足本次写入操作的最小容量 minNewCapacity 不能超过 maxCapacity

if (minNewCapacity > maxCapacity) {

throw new IllegalArgumentException(String.format(

"minNewCapacity: %d (expected: not greater than maxCapacity(%d)",

minNewCapacity, maxCapacity));

}

// 用于决定扩容的尺度

final int threshold =laipuhuo.com CALCULATE_THRESHOLD; // 4 MiB page

if (minNewCapacity == threshold) {

return threshold;

}

// If over threshold, do not double but just increase by threshold.

if (minNewCapacity > threshold) {

// 计算扩容基准线。

// 要求必须是 CALCULATE_THRESHOLD 的最小倍数,而且必须要小于等于 minNewCapacity

int newCapacity laipuhuo.com= minNewCapacity / threshold * threshold;

if (newCapacity > maxCapacity - threshold) {

newCapacity = maxCapacity;

} else {

// 按照 threshold (4M)扩容

newCapacity = threshold;

}

return laipuhuo.com newCapacity;

}

// Not over threshold. Double up to 4 MiB, starting from 64.

// 按照 64 的倍数进行扩容。但 newCapacity 需要大于等于 minNewCapacity。

int newCapacity = 64;

while (newCapacity < minNewCapacity) {

newCapacity <<= 1;

}

return Math.min laipuhuo.com (newCapacity, maxCapacity);

}

}

0 人点赞