package com.wizzardo.tools.misc.pool;

import com.wizzardo.tools.misc.Consumer;
import com.wizzardo.tools.misc.Supplier;

import java.util.LinkedList;
import java.util.Queue;

/**
 * Created by wizzardo on 30.06.15.
 */
public class PoolBuilder<T> {

    protected Supplier<T> supplier = new Supplier<T>() {
        @Override
        public T supply() {
            return null;
        }
    };

    protected Consumer<T> resetter = new Consumer<T>() {
        @Override
        public void consume(T t) {
        }
    };

    protected HolderSupplier<T> holderSupplier = new HolderSupplier<T>() {
        @Override
        public Holder<T> get(Pool<T> pool, T value, final Consumer<T> resetter) {
            return new SoftHolder<T>(pool, value) {
                @Override
                public T get() {
                    T t = super.get();
                    resetter.consume(t);
                    return t;
                }
            };
        }
    };

    protected Supplier<Queue<Holder<T>>> queueSupplier = new Supplier<Queue<Holder<T>>>() {
        ThreadLocal<Queue<Holder<T>>> queue = new ThreadLocal<Queue<Holder<T>>>() {
            @Override
            protected Queue<Holder<T>> initialValue() {
                return new LinkedList<Holder<T>>();
            }
        };

        @Override
        public Queue<Holder<T>> supply() {
            return queue.get();
        }
    };

    public PoolBuilder<T> queue(Supplier<Queue<Holder<T>>> queueSupplier) {
        this.queueSupplier = queueSupplier;
        return this;
    }

    public PoolBuilder<T> holder(HolderSupplier<T> holderSupplier) {
        this.holderSupplier = holderSupplier;
        return this;
    }

    public PoolBuilder<T> supplier(Supplier<T> supplier) {
        this.supplier = supplier;
        return this;
    }

    public PoolBuilder<T> resetter(Consumer<T> resetter) {
        this.resetter = resetter;
        return this;
    }

    public Pool<T> build() {
        return new AbstractQueuedPool<T>() {
            @Override
            public T create() {
                return supplier.supply();
            }

            @Override
            protected Queue<Holder<T>> queue() {
                return queueSupplier.supply();
            }

            @Override
            protected Holder<T> createHolder(T t) {
                return holderSupplier.get(this, t, resetter);
            }
        };
    }

    public interface HolderSupplier<T> {
        Holder<T> get(Pool<T> pool, T value, Consumer<T> resetter);
    }
}

@@ -167,16 +167,67 @@
 l.Queue;
+%0Aimport java.util.concurrent.ConcurrentLinkedQueue;
 %0A%0A/**%0A *
@@ -1064,32 +1064,166 @@
  queueSupplier =
+ createThreadLocalQueueSupplier();%0A%0A    public static %3CT%3E Supplier%3CQueue%3CHolder%3CT%3E%3E%3E createThreadLocalQueueSupplier() %7B%0A        return
  new Supplier%3CQu
@@ -1234,32 +1234,36 @@
 Holder%3CT%3E%3E%3E() %7B%0A
+    
         ThreadLo
@@ -1334,32 +1334,36 @@
 ) %7B%0A            
+  
+  
 @Override%0A      
@@ -1348,32 +1348,36 @@
       @Override%0A
+    
             prot
@@ -1424,32 +1424,36 @@
                 
+  
+  
 return new Linke
@@ -1484,26 +1484,33 @@
         
-%7D%0A
+    %7D%0A   
         
 %7D;%0A%0A    
@@ -1497,28 +1497,33 @@
 %0A           
+ 
 %7D;%0A%0A
+    
         @Ove
@@ -1532,24 +1532,28 @@
 ide%0A        
+  
+  
 public Queue
@@ -1579,32 +1579,36 @@
 ) %7B%0A            
+    
 return queue.get
@@ -1615,32 +1615,384 @@
 ();%0A        
+  
-%7D%0A    %7D;
+  %7D%0A        %7D;%0A    %7D%0A%0A    public static %3CT%3E Supplier%3CQueue%3CHolder%3CT%3E%3E%3E createSharedQueueSupplier() %7B%0A        return new Supplier%3CQueue%3CHolder%3CT%3E%3E%3E() %7B%0A            Queue%3CHolder%3CT%3E%3E queue = new ConcurrentLinkedQueue%3CHolder%3CT%3E%3E();%0A%0A            @Override%0A            public Queue%3CHolder%3CT%3E%3E supply() %7B%0A                return queue;%0A            %7D%0A        %7D;%0A    %7D
 %0A%0A    public

add sharedQueueSupplier