package org.jctools.jmh.counters;

import org.jctools.counters.FixedSizeStripedLongCounter;
import org.jctools.maps.ConcurrentAutoTable;
import org.openjdk.jmh.annotations.CompilerControl;
import org.openjdk.jmh.annotations.CompilerControl.Mode;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author Tolstopyatov Vsevolod
 */
public class CountersFactory {

    public enum CounterType {
        AtomicLong,
        LongAdder,
        FixedSizeStripedV6,
        FixedSizeStripedV8,
        CAT
    }

    static Counter build(CounterType type, int stripes) {
        switch (type) {
            case AtomicLong:
                return new AtomicLongCounter();
            case LongAdder:
                return new LongAdderCounter();
            case FixedSizeStripedV6:
                return new FixedSizeStripedCounter(
                    org.jctools.counters.CountersFactory.createFixedSizeStripedCounterV6(stripes));
            case FixedSizeStripedV8:
                return new FixedSizeStripedCounter(
                    org.jctools.counters.CountersFactory.createFixedSizeStripedCounterV8(stripes));
            case CAT:
                return new ConcurrentAutoTableCounter();
            default:
                throw new IllegalArgumentException();
        }
    }

    // For consistent and fair benchmarking, always use counter as field

    static class AtomicLongCounter extends Counter {
        private final AtomicLong counter = new AtomicLong();

        @Override
        @CompilerControl(Mode.INLINE)
        public void inc() {
            counter.incrementAndGet();
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public long get() {
            return counter.get();
        }
    }

    static class LongAdderCounter extends Counter {
        private final LongAdder counter = new LongAdder();

        @Override
        @CompilerControl(Mode.INLINE)
        public void inc() {
            counter.increment();
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public long get() {
            return counter.sum();
        }
    }

    static class FixedSizeStripedCounter extends Counter {
        private final FixedSizeStripedLongCounter counter;

        public FixedSizeStripedCounter(FixedSizeStripedLongCounter impl) {
            counter = impl;
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public void inc() {
            counter.inc();
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public long get() {
            return counter.get();
        }
    }

    static class ConcurrentAutoTableCounter extends Counter {
        private final ConcurrentAutoTable counter;

        public ConcurrentAutoTableCounter() {
            counter = new ConcurrentAutoTable();
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public void inc() {
            counter.add(1);
        }

        @Override
        @CompilerControl(Mode.INLINE)
        public long get() {
            return counter.get();
        }
    }
}

@@ -28,16 +28,279 @@
 nters;%0A%0A
+import static org.jctools.counters.CountersFactory.createFixedSizeStripedCounterV6;%0Aimport static org.jctools.counters.CountersFactory.createFixedSizeStripedCounterV8;%0A%0Aimport java.util.concurrent.atomic.AtomicLong;%0Aimport java.util.concurrent.atomic.LongAdder;%0A%0A
 import o
@@ -348,16 +348,16 @@
 ounter;%0A
-
 import o
@@ -507,102 +507,8 @@
 e;%0A%0A
-import java.util.concurrent.atomic.AtomicLong;%0Aimport java.util.concurrent.atomic.LongAdder;%0A%0A
 /**%0A
@@ -806,28 +806,24 @@
 ) %7B%0A        
-    
 case AtomicL
@@ -827,20 +827,16 @@
 icLong:%0A
-    
         
@@ -875,28 +875,24 @@
 ();%0A        
-   
- 
 case LongAdd
@@ -895,20 +895,16 @@
 gAdder:%0A
-    
         
@@ -938,36 +938,32 @@
 nter();%0A        
-    
 case FixedSizeSt
@@ -975,36 +975,32 @@
 V6:%0A            
- 
-   
 return new Fixed
@@ -1022,66 +1022,8 @@
 ter(
-%0A                    org.jctools.counters.CountersFactory.
 crea
@@ -1065,28 +1065,24 @@
 ));%0A        
-    
 case FixedSi
@@ -1094,20 +1094,16 @@
 ipedV8:%0A
-    
         
@@ -1145,66 +1145,8 @@
 ter(
-%0A                    org.jctools.counters.CountersFactory.
 crea
@@ -1188,28 +1188,24 @@
 ));%0A        
-    
 case CAT:%0A  
@@ -1206,36 +1206,32 @@
 AT:%0A            
-  
-  
 return new Concu
@@ -1263,20 +1263,16 @@
         
-    
 default:
@@ -1272,20 +1272,16 @@
 efault:%0A
-    
         
@@ -1550,46 +1550,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -1646,46 +1646,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -1855,46 +1855,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -1945,46 +1945,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -2275,46 +2275,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -2359,46 +2359,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -2676,46 +2676,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     
@@ -2731,32 +2731,32 @@
 (1);%0A        %7D%0A%0A
+
         @Overrid
@@ -2761,46 +2761,8 @@
 ide%0A
-        @CompilerControl(Mode.INLINE)%0A
     

Tidy up