kafka的缓存池源码

public final class BufferPool {
    private final long totalMemory;
    private final int poolableSize;
    private final ReentrantLock lock;
    private final Deque<ByteBuffer> free;
    private final Deque<Condition> waiters;
    private long availableMemory;
    private final Metrics metrics;
    private final Time time;
    private final Sensor waitTime;

    public BufferPool(long memory, int poolableSize, Metrics metrics, Time time, String metricGrpName) {
        this.poolableSize = poolableSize;
        this.lock = new ReentrantLock();
        this.free = new ArrayDeque();
        this.waiters = new ArrayDeque();
        this.totalMemory = memory;
        this.availableMemory = memory;
        this.metrics = metrics;
        this.time = time;
        this.waitTime = this.metrics.sensor("bufferpool-wait-time");
        MetricName metricName = metrics.metricName("bufferpool-wait-ratio", metricGrpName, "The fraction of time an appender waits for space allocation.");
        this.waitTime.add(metricName, new Rate(TimeUnit.NANOSECONDS));
    }

    public ByteBuffer allocate(int size, long maxTimeToBlockMs) throws InterruptedException {
        if ((long)size > this.totalMemory) {
            throw new IllegalArgumentException("Attempt to allocate " + size + " bytes, but there is a hard limit of " + this.totalMemory + " on memory allocations.");
        } else {
            this.lock.lock();

            ByteBuffer var5;
            try {
                if (size == this.poolableSize && !this.free.isEmpty()) {
                    ByteBuffer var31 = (ByteBuffer)this.free.pollFirst();
                    return var31;
                }

                int freeListSize = this.free.size() * this.poolableSize;
                if (this.availableMemory + (long)freeListSize < (long)size) {
                    int accumulated = 0;
                    ByteBuffer buffer = null;
                    Condition moreMemory = this.lock.newCondition();
                    long remainingTimeToBlockNs = TimeUnit.MILLISECONDS.toNanos(maxTimeToBlockMs);
                    this.waiters.addLast(moreMemory);

                    while(accumulated < size) {
                        long startWaitNs = this.time.nanoseconds();
                        boolean var27 = false;

                        long timeNs;
                        boolean waitingTimeElapsed;
                        try {
                            var27 = true;
                            waitingTimeElapsed = !moreMemory.await(remainingTimeToBlockNs, TimeUnit.NANOSECONDS);
                            var27 = false;
                        } catch (InterruptedException var28) {
                            this.waiters.remove(moreMemory);
                            throw var28;
                        } finally {
                            if (var27) {
                                long endWaitNs = this.time.nanoseconds();
                                timeNs = Math.max(0L, endWaitNs - startWaitNs);
                                this.waitTime.record((double)timeNs, this.time.milliseconds());
                            }
                        }

                        long endWaitNs = this.time.nanoseconds();
                        timeNs = Math.max(0L, endWaitNs - startWaitNs);
                        this.waitTime.record((double)timeNs, this.time.milliseconds());
                        if (waitingTimeElapsed) {
                            this.waiters.remove(moreMemory);
                            throw new TimeoutException("Failed to allocate memory within the configured max blocking time " + maxTimeToBlockMs + " ms.");
                        }

                        remainingTimeToBlockNs -= timeNs;
                        if (accumulated == 0 && size == this.poolableSize && !this.free.isEmpty()) {
                            buffer = (ByteBuffer)this.free.pollFirst();
                            accumulated = size;
                        } else {
                            this.freeUp(size - accumulated);
                            int got = (int)Math.min((long)(size - accumulated), this.availableMemory);
                            this.availableMemory -= (long)got;
                            accumulated += got;
                        }
                    }

                    Condition removed = (Condition)this.waiters.removeFirst();
                    if (removed != moreMemory) {
                        throw new IllegalStateException("Wrong condition: this shouldn't happen.");
                    }

                    if ((this.availableMemory > 0L || !this.free.isEmpty()) && !this.waiters.isEmpty()) {
                        ((Condition)this.waiters.peekFirst()).signal();
                    }

                    this.lock.unlock();
                    ByteBuffer var11;
                    if (buffer == null) {
                        var11 = ByteBuffer.allocate(size);
                        return var11;
                    }

                    var11 = buffer;
                    return var11;
                }

                this.freeUp(size);
                this.availableMemory -= (long)size;
                this.lock.unlock();
                var5 = ByteBuffer.allocate(size);
            } finally {
                if (this.lock.isHeldByCurrentThread()) {
                    this.lock.unlock();
                }

            }

            return var5;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值