package org.beetl.core.cache;

import org.beetl.core.annotation.NonThreadSafety;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.function.Supplier;

/**
 * TODO3，需要性能压测
 * 模板渲染和计算中需要的临时存储空间，缓存以提高性能
 */
@NonThreadSafety
public class ContextLocalBuffers {

    /** ContextBuffer 队列 */
    private final ArrayBlockingQueue<ContextBuffer> queue  ;
    /** 字节数组与字符数组的最大容量 */
    private final int bufferMax;

    ThreadLocal<ContextBuffer> local = ThreadLocal.withInitial(new Supplier<ContextBuffer>() {
        @Override
        public ContextBuffer get() {
            return new ContextBuffer(256);
        }
    });

    /**
     * 构造方法
     *
     * @param num       队列的大小
     * @param bufferMax 字节数组与字符数组的最大容量
     */
    public ContextLocalBuffers(int num, int bufferMax) {
        if(num!=0){
            this.bufferMax = bufferMax;
            queue = new ArrayBlockingQueue<>(num);
            for (int i = 0; i < num; i++) {
                ContextBuffer buffer = new ContextBuffer(bufferMax, true);
                queue.add(buffer);
            }
        }else{
            this.queue =null;
            this.bufferMax = bufferMax;
        }

    }

    /**
     * 获取一个 ContextBuffer 实例
     *
     * @return 从队列中返回一个实例，如果没有则创建一个
     */
    @NotNull
    public ContextBuffer getContextLocalBuffer() {
        if(queue==null){
            return local.get();
        }else{
            ContextBuffer buffer = queue.poll();
            return buffer == null ? new ContextBuffer(bufferMax, false) : buffer;
        }

    }

    /**
     * 将一个 ContextBuffer 实例回收到队列中
     *
     * @param buffer 一个 ContextBuffer 实例
     */
    public void putContextLocalBuffer(@NotNull ContextBuffer buffer) {
        if (!buffer.inner) {
            // 放弃，这是临时生成的
            return;
        }
        if(queue!=null){
            queue.add(buffer);
        }
        //thread local

    }

}
