package com.huashe.common.utils.uuid;

import com.huashe.common.utils.DateUtils;
import com.huashe.common.utils.StringUtils;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @author ruoyi 序列生成类
 */
public class Seq
{
    // 通用序列类型
    public static final String commSeqType = "COMMON";

    // 上传序列类型
    public static final String uploadSeqType = "UPLOAD";

    // 通用接口序列数
    private static AtomicInteger commSeq = new AtomicInteger(1);

    // 上传接口序列数
    private static AtomicInteger uploadSeq = new AtomicInteger(1);

    // 机器标识
    private static final String machineCode = "A";

    /**
     * 获取通用序列号
     *
     * @return 序列值
     */
    public static String getId()
    {
        return getId(commSeqType);
    }

    public static String getIdWidthPrefix(String prefix) {
        return prefix + getId(commSeqType);
    }

    /**
     * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
     *
     * @return 序列值
     */
    public static String getId(String type)
    {
        AtomicInteger atomicInt = commSeq;
        if (uploadSeqType.equals(type))
        {
            atomicInt = uploadSeq;
        }
        return getId(atomicInt, 3);
    }

    /**
     * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
     *
     * @param atomicInt 序列数
     * @param length 数值长度
     * @return 序列值
     */
    public static String getId(AtomicInteger atomicInt, int length)
    {
        String result = DateUtils.dateTimeNow("yyMMddHHmmss");
        result += machineCode;
        result += getSeq(atomicInt, length);
        return result;
    }

    /**
     * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
     *
     * @return 序列值
     */
    private synchronized static String getSeq(AtomicInteger atomicInt, int length)
    {
        // 先取值再+1
        int value = atomicInt.getAndIncrement();

        // 如果更新后值>=10 的 (length)幂次方则重置为1
        int maxSeq = (int) Math.pow(10, length);
        if (atomicInt.get() >= maxSeq)
        {
            atomicInt.set(1);
        }
        // 转字符串，用0左补齐
        return StringUtils.padl(value, length);
    }

    public static void main(String[] args) {
        // 线程数=count*count
        int count = 10;
        final long[][] times = new long[count][100];

        Thread[] threads = new Thread[count];
        for (int i = 0; i < threads.length; i++) {
            final int ip = i;
            threads[i] = new Thread() {
                @Override
                public void run() {
                    for (int j = 0; j < 10; j++) {
                        long t1 = System.nanoTime();// 该函数是返回纳秒的。1毫秒=1纳秒*1000000

                        System.out.println(Seq.getId());// 测试

                        long t = System.nanoTime() - t1;

                        times[ip][j] = t;// 求平均
                    }
                }

            };
        }

        long lastMilis = System.currentTimeMillis();
        // 逐个启动线程
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }

        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        /**
         * 1、QPS：系统每秒处理的请求数（query per second） 2、RT：系统的响应时间，一个请求的响应时间，也可以是一段时间的平均值 3、最佳线程数量：刚好消耗完服务器瓶颈资源的临界线程数
         * 对于单线程：QPS=1000/RT 对于多线程：QPS=1000*线程数量/RT
         */
        long time = System.currentTimeMillis() - lastMilis;
        System.out.println("QPS: " + (1000 * count / time));

        long sum = 0;
        long max = 0;
        for (int i = 0; i < times.length; i++) {
            for (int j = 0; j < times[i].length; j++) {
                sum += times[i][j];

                if (times[i][j] > max) {
                    max = times[i][j];
                }
            }
        }
        System.out.println("Sum(ms)" + time);
        System.out.println("AVG(ms): " + sum / 1000000 / (count * 100));
        System.out.println("MAX(ms): " + max / 1000000);
    }
}
