package ALBasicServer.ALServerSynTask;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.concurrent.locks.ReentrantLock;
import ALBasicServer.ALTask._IALSynTask;
import ALServerLog.ALServerLog;
/*******************
* 定时任务的划片集合节点信息
*
* @author alzq.z
* @email zhuangfan@vip.163.com
* @time Jul 16, 2015 10:57:02 PM
*/
public class ALSynTimingTaskNode
{
/** 当前回合标记 */
private int _m_iCurRound;
/** 当前回合的本节点定时任务队列 */
private LinkedList<_IALSynTask> _m_lCurRoundTimingTaskList;
/** 下一回合标记 */
private int _m_iNextRound;
/** 固定记录下一回合的延迟任务队列集合 */
private LinkedList<_IALSynTask> _m_lNextRoundTimingTaskList;
/** 非本回合与下一回合的较长时间延迟任务信息集合队列 */
private LinkedList<ALSynTimingTaskNodeFarDelayTaskInfo> _m_lFarDelayTaskList;
/** 本节点下的数据锁 */
private ReentrantLock _m_mutex;
public ALSynTimingTaskNode(int _round)
{
_m_iCurRound = _round;
_m_lCurRoundTimingTaskList = new LinkedList<_IALSynTask>();
_m_iNextRound = _round + 1;
_m_lNextRoundTimingTaskList = new LinkedList<_IALSynTask>();
_m_lFarDelayTaskList = new LinkedList<ALSynTimingTaskNodeFarDelayTaskInfo>();
_m_mutex = new ReentrantLock();
}
/***************
* 添加指定回合的本时间节点的任务,返回是否添加成功,不成功则表示需要马上执行
*
* @author alzq.z
* @time Jul 16, 2015 11:26:06 PM
*/
public boolean addTimingTask(int _round, _IALSynTask _task)
{
_lock();
try
{
if(null == _task)
return false;
//当本回合的时候,直接进行添加
if(_round == _m_iCurRound)
{
_m_lCurRoundTimingTaskList.add(_task);
return true;
}
else if(_round == _m_iNextRound)
{
_m_lNextRoundTimingTaskList.add(_task);
return true;
}
else if(_round > _m_iNextRound)
{
//长时间延迟的任务,按照回合顺序放入对应队列
ListIterator<ALSynTimingTaskNodeFarDelayTaskInfo> iterator = _m_lFarDelayTaskList.listIterator();
while(iterator.hasNext())
{
ALSynTimingTaskNodeFarDelayTaskInfo taskInfo = iterator.next();
if(taskInfo.getRound() == _round)
{
//匹配回合则加入本节点
taskInfo.addSynTask(_task);
break;
}
else if(taskInfo.getRound() < _round)
{
//当插入的回合比对应回合早,则需要在对应回合之前插入数据
//这里采用的做法是将本节点数据重复插入到下一个节点,之后将本节点设置为新数据
iterator.add(taskInfo);
//创建新节点
ALSynTimingTaskNodeFarDelayTaskInfo newInfo = new ALSynTimingTaskNodeFarDelayTaskInfo(_round);
iterator.set(newInfo);
//插入任务
newInfo.addSynTask(_task);
break;
}
}
//判断是否已经到了最后节点
if(!iterator.hasNext())
{
//在最后节点则往最后追加数据
//创建新节点
ALSynTimingTaskNodeFarDelayTaskInfo newInfo = new ALSynTimingTaskNodeFarDelayTaskInfo(_round);
iterator.add(newInfo);
//插入任务
newInfo.addSynTask(_task);
}
return true;
}
else
{
//当回合小于当前回合则表示失败,外部需要直接处理
return false;
}
}
finally
{
_unlock();
}
}
/***************
* 取出所有对应回合的本节点任务
*
* @author alzq.z
* @time Jul 16, 2015 11:49:51 PM
*/
public void popAllRoundTaskAndMoveNextRound(int _round, LinkedList<_IALSynTask> _recList)
{
if(null == _recList)
return ;
_lock();
try
{
//判断回合是否在本回合之前,则不做处理
if(_round < _m_iCurRound)
return ;
//将所有当前回合任务放入队列
while(!_m_lCurRoundTimingTaskList.isEmpty())
{
_recList.addLast(_m_lCurRoundTimingTaskList.pop());
}
//当回合在本回合之后则弹出错误警告,并将所有对应回合之后的任务放入队列
if(_round > _m_iCurRound)
{
//可能跳过某个回合,因此输出错误
ALServerLog.Fatal("Timing Syn Task Round Error! pop round: " + _round + " - current round: " + _m_iCurRound);
//移动到对应的回合
_moveToRound(_round);
//将所有当前回合任务放入队列
while(!_m_lCurRoundTimingTaskList.isEmpty())
{
_recList.addLast(_m_lCurRoundTimingTaskList.pop());
}
}
//移动到下一回合
_moveNextRound();
}
finally
{
_unlock();
}
}
/****************
* 移动当前回合至指定回合
*
* @author alzq.z
* @time Jul 16, 2015 11:57:27 PM
*/
protected void _moveToRound(int _targetRound)
{
//在不匹配对应回合的时候不断往后推移
while(_m_iCurRound < _targetRound)
{
_moveNextRound();
}
}
/***************
* 向下移动一个回合
*
* @author alzq.z
* @time Jul 16, 2015 11:58:23 PM
*/
protected void _moveNextRound()
{
//累加一个回合
_m_iCurRound++;
_m_iNextRound++;
//将下一回合任务累加到当前队列
while(!_m_lNextRoundTimingTaskList.isEmpty())
{
_m_lCurRoundTimingTaskList.addLast(_m_lNextRoundTimingTaskList.pop());
}
//获取第一个长时间间隔任务队列节点,是否匹配下一回合,是则将任务放入
if(!_m_lFarDelayTaskList.isEmpty())
{
ALSynTimingTaskNodeFarDelayTaskInfo farDelayInfo = _m_lFarDelayTaskList.getFirst();
if(farDelayInfo.getRound() == _m_iNextRound)
{
//从长时间间隔队列删除
_m_lFarDelayTaskList.pop();
//将任务放入
farDelayInfo.popAllSynTask(_m_lNextRoundTimingTaskList);
}
}
}
protected void _lock(){_m_mutex.lock();}
protected void _unlock() {_m_mutex.unlock();}
}