package com.brilliance.isc.counter.service.impl;

import com.brilliance.isc.counter.mapper.CounterMapperOfCou;
import com.brilliance.isc.counter.service.SegmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class SegmentServiceImpl implements SegmentService {

    @Autowired
    private CounterMapperOfCou counterMapper;

    @Autowired
    private SegmentCounter segmentCounter;
    /**
     * 更新本地数据库表，获取最新的号段缓存
     * 使用局部事务，保证缓冲刷新后数据库COU立即更新提交，不受外部事务影响。
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public SegmentCounter.Segment updateSegment(boolean isNew, String key, long start, int len) {
        int cnt;
        if (isNew) {
            //Redis中不存在数据，先乐观update
            cnt = counterMapper.updateCounter(key, len);
            if (cnt == 0) {
                //数据库不在计数序列
                long cur = start;
                long max = cur + len;
                counterMapper.insertNewCounter(key, max);
                return new SegmentCounter.Segment(cur, max);
            } else {
                //数据库中已存在，只是Redis没有

                return update(key, len);
            }
        } else {
            //Redis存在key，所以直接更新取号
            cnt = counterMapper.updateCounter(key, len);
            if(cnt == 0){
                //避免redis有数据，但是数据库不存在的情况
                Long cur = segmentCounter.evalCur(key);
                return updateSegment(true, key, cur, len);
            }else {
                return update(key, len);
            }
        }

    }

    private SegmentCounter.Segment update(String key, int len){
        //TODO  可能会废了10个号
        long max = counterMapper.selectCurrent(key);
        long cur = max - len;
        return new SegmentCounter.Segment(cur, max);
    }
}
