// Path: core/src/main/java/com/github/phantomthief/util/SimpleRateLimiter.java
// @ThreadSafe
// public class SimpleRateLimiter {
// 
//     private final LongAdder skip = new LongAdder();
// 
//     /**
//      * 多少ns允许一次请求
//      */
//     private long allowTimesPerNanos;
//     private volatile long lastAcquiredNanos;
// 
//     private SimpleRateLimiter(long allowTimesPerNanos) {
//         checkState(allowTimesPerNanos > 0);
//         this.allowTimesPerNanos = allowTimesPerNanos;
//     }
// 
//     /**
//      * 创建一个{@link SimpleRateLimiter}对象，限制每次的时间间隔
//      *
//      * @param periodPerTimes 时间间隔
//      * @return {@link SimpleRateLimiter}对象
//      */
//     public static SimpleRateLimiter createByPeriod(Duration periodPerTimes) {
//         return new SimpleRateLimiter(checkNotNull(periodPerTimes).toNanos());
//     }
// 
//     /**
//      * 创建一个{@link SimpleRateLimiter}对象，限制每秒允许的请求次数
//      *
//      * @param permitsPerSecond 请求次数
//      * @return {@link SimpleRateLimiter}对象
//      */
//     public static SimpleRateLimiter create(double permitsPerSecond) {
//         checkState(permitsPerSecond > 0);
//         long allowTimesPerNanos = (long) (SECONDS.toNanos(1) / permitsPerSecond);
//         return new SimpleRateLimiter(allowTimesPerNanos);
//     }
// 
//     /**
//      * 设置当前{@link SimpleRateLimiter}对象每秒允许的请求次数
//      *
//      * @param permitsPerSecond 每秒请求次数
//      */
//     public void setRate(double permitsPerSecond) {
//         checkState(permitsPerSecond > 0);
//         long thisPeriod = (long) (SECONDS.toNanos(1) / permitsPerSecond);
//         checkState(thisPeriod > 0);
//         this.allowTimesPerNanos = thisPeriod;
//     }
// 
//     /**
//      * 设置当前{@link SimpleRateLimiter}对象每次请求的间隔时间
//      *
//      * @param periodPerTimes 间隔时间
//      */
//     public void setPeriod(Duration periodPerTimes) {
//         long thisPeriod = checkNotNull(periodPerTimes).toNanos();
//         checkState(thisPeriod > 0);
//         this.allowTimesPerNanos = thisPeriod;
//     }
// 
//     long getAllowTimesPerNanos() {
//         return allowTimesPerNanos;
//     }
// 
//     /**
//      * 判断本次请求是否获得准许处理请求
//      *
//      * @return 是否获得准许
//      */
//     public boolean tryAcquire() {
//         long nanoTime = System.nanoTime();
//         if (nanoTime >= lastAcquiredNanos + allowTimesPerNanos || lastAcquiredNanos == 0) {
//             synchronized (this) {
//                 if (nanoTime >= lastAcquiredNanos + allowTimesPerNanos || lastAcquiredNanos == 0) {
//                     lastAcquiredNanos = nanoTime;
//                     return true;
//                 }
//             }
//         }
//         skip.increment();
//         return false;
//     }
// 
//     /**
//      * 计算到上次执行本操作前，共计多少个没有获取到准许，计算完成后重新计数
//      *
//      * @return 累计跳过的请求数
//      */
//     public long getSkipCountAndClear() {
//         return skip.sumThenReset();
//     }
// }


import java.util.Collection;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import com.github.phantomthief.util.SimpleRateLimiter;
package com.github.phantomthief.pool.impl;



/**
 * 备注，本类主要是用于给
 * {@link com.github.phantomthief.pool.KeyAffinityExecutor#newSerializingExecutor(IntSupplier, IntSupplier, String)}
 * 提供支持的，并不推荐大家直接使用，未来也可能会随时调整实现和行为
 *
 * @author w.vela
 * Created on 2020-08-19.
 */
public class DynamicCapacityLinkedBlockingQueue<E> implements BlockingQueue<E> {

    private final CapacitySettableLinkedBlockingQueue<E> queue;
    private final IntSupplier capacity;
// Path: core/src/main/java/com/github/phantomthief/util/SimpleRateLimiter.java
// @ThreadSafe
// public class SimpleRateLimiter {
// 
//     private final LongAdder skip = new LongAdder();
// 
//     /**
//      * 多少ns允许一次请求
//      */
//     private long allowTimesPerNanos;
//     private volatile long lastAcquiredNanos;
// 
//     private SimpleRateLimiter(long allowTimesPerNanos) {
//         checkState(allowTimesPerNanos > 0);
//         this.allowTimesPerNanos = allowTimesPerNanos;
//     }
// 
//     /**
//      * 创建一个{@link SimpleRateLimiter}对象，限制每次的时间间隔
//      *
//      * @param periodPerTimes 时间间隔
//      * @return {@link SimpleRateLimiter}对象
//      */
//     public static SimpleRateLimiter createByPeriod(Duration periodPerTimes) {
//         return new SimpleRateLimiter(checkNotNull(periodPerTimes).toNanos());
//     }
// 
//     /**
//      * 创建一个{@link SimpleRateLimiter}对象，限制每秒允许的请求次数
//      *
//      * @param permitsPerSecond 请求次数
//      * @return {@link SimpleRateLimiter}对象
//      */
//     public static SimpleRateLimiter create(double permitsPerSecond) {
//         checkState(permitsPerSecond > 0);
//         long allowTimesPerNanos = (long) (SECONDS.toNanos(1) / permitsPerSecond);
//         return new SimpleRateLimiter(allowTimesPerNanos);
//     }
// 
//     /**
//      * 设置当前{@link SimpleRateLimiter}对象每秒允许的请求次数
//      *
//      * @param permitsPerSecond 每秒请求次数
//      */
//     public void setRate(double permitsPerSecond) {
//         checkState(permitsPerSecond > 0);
//         long thisPeriod = (long) (SECONDS.toNanos(1) / permitsPerSecond);
//         checkState(thisPeriod > 0);
//         this.allowTimesPerNanos = thisPeriod;
//     }
// 
//     /**
//      * 设置当前{@link SimpleRateLimiter}对象每次请求的间隔时间
//      *
//      * @param periodPerTimes 间隔时间
//      */
//     public void setPeriod(Duration periodPerTimes) {
//         long thisPeriod = checkNotNull(periodPerTimes).toNanos();
//         checkState(thisPeriod > 0);
//         this.allowTimesPerNanos = thisPeriod;
//     }
// 
//     long getAllowTimesPerNanos() {
//         return allowTimesPerNanos;
//     }
// 
//     /**
//      * 判断本次请求是否获得准许处理请求
//      *
//      * @return 是否获得准许
//      */
//     public boolean tryAcquire() {
//         long nanoTime = System.nanoTime();
//         if (nanoTime >= lastAcquiredNanos + allowTimesPerNanos || lastAcquiredNanos == 0) {
//             synchronized (this) {
//                 if (nanoTime >= lastAcquiredNanos + allowTimesPerNanos || lastAcquiredNanos == 0) {
//                     lastAcquiredNanos = nanoTime;
//                     return true;
//                 }
//             }
//         }
//         skip.increment();
//         return false;
//     }
// 
//     /**
//      * 计算到上次执行本操作前，共计多少个没有获取到准许，计算完成后重新计数
//      *
//      * @return 累计跳过的请求数
//      */
//     public long getSkipCountAndClear() {
//         return skip.sumThenReset();
//     }
// }


// Path: core/src/main/java/com/github/phantomthief/pool/impl/DynamicCapacityLinkedBlockingQueue.java
import java.util.Collection;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import com.github.phantomthief.util.SimpleRateLimiter;

package com.github.phantomthief.pool.impl;



/**
 * 备注，本类主要是用于给
 * {@link com.github.phantomthief.pool.KeyAffinityExecutor#newSerializingExecutor(IntSupplier, IntSupplier, String)}
 * 提供支持的，并不推荐大家直接使用，未来也可能会随时调整实现和行为
 *
 * @author w.vela
 * Created on 2020-08-19.
 */
public class DynamicCapacityLinkedBlockingQueue<E> implements BlockingQueue<E> {

    private final CapacitySettableLinkedBlockingQueue<E> queue;
    private final IntSupplier capacity;
    private final SimpleRateLimiter rateLimiter;