package cn.quantgroup.xyqb.util;

import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicLong;

/**
 * @author hechao
 * @description
 * @date 2020/7/24 13:45
 * @modify 2020/7/24 13:45 by hechao
 */
@Component
public class AtomicSequencer {

    private final AtomicLong INDEX = new AtomicLong(1L);

    private IdentitySequencer sequencer;

    public AtomicSequencer(IdentitySequencer sequencer) {
        this.sequencer = sequencer;
    }

    public IdentitySequencer sequencer() {
        return sequencer;
    }

    public long nextId() {
        return nextId(INDEX.addAndGet(1L));
    }

    public long nextId(long position) {
        return sequencer.nextId(Math.max(position % 225L, 1L));
    }

    public long workerId() {
        return sequencer.workerId();
    }

    public long index() {
        return INDEX.get();
    }

    public static long extractPosition(long id) {
        return ((id >> 8 << 8) ^ id);
    }

    public int partitionKey(long id) {
        return (int) ((id >> 8 << 8) ^ id);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Sequencer{")
                .append("INDEX = ").append(index())
                .append(",sequencer = ").append(sequencer)
                .append("}");
        return sb.toString();
    }
}