// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.channel;

import io.netty.util.internal.AdaptiveCalculator;
import io.netty.util.internal.ObjectUtil;

public class AdaptiveRecvByteBufAllocator extends DefaultMaxMessagesRecvByteBufAllocator
{
    public static final int DEFAULT_MINIMUM = 64;
    public static final int DEFAULT_INITIAL = 2048;
    public static final int DEFAULT_MAXIMUM = 65536;
    @Deprecated
    public static final AdaptiveRecvByteBufAllocator DEFAULT;
    private final int minimum;
    private final int initial;
    private final int maximum;
    
    public AdaptiveRecvByteBufAllocator() {
        this(64, 2048, 65536);
    }
    
    public AdaptiveRecvByteBufAllocator(final int minimum, final int initial, final int maximum) {
        ObjectUtil.checkPositive(minimum, "minimum");
        if (initial < minimum) {
            throw new IllegalArgumentException("initial: " + initial);
        }
        if (maximum < initial) {
            throw new IllegalArgumentException("maximum: " + maximum);
        }
        this.minimum = minimum;
        this.initial = initial;
        this.maximum = maximum;
    }
    
    @Override
    public RecvByteBufAllocator.Handle newHandle() {
        return new HandleImpl(this.minimum, this.initial, this.maximum);
    }
    
    @Override
    public AdaptiveRecvByteBufAllocator respectMaybeMoreData(final boolean respectMaybeMoreData) {
        super.respectMaybeMoreData(respectMaybeMoreData);
        return this;
    }
    
    static {
        DEFAULT = new AdaptiveRecvByteBufAllocator();
    }
    
    private final class HandleImpl extends MaxMessageHandle
    {
        private final AdaptiveCalculator calculator;
        
        HandleImpl(final int minimum, final int initial, final int maximum) {
            this.calculator = new AdaptiveCalculator(minimum, initial, maximum);
        }
        
        @Override
        public void lastBytesRead(final int bytes) {
            if (bytes == this.attemptedBytesRead()) {
                this.calculator.record(bytes);
            }
            super.lastBytesRead(bytes);
        }
        
        @Override
        public int guess() {
            return this.calculator.nextSize();
        }
        
        @Override
        public void readComplete() {
            this.calculator.record(this.totalBytesRead());
        }
    }
}
