Mercurial > hg > RemoteEditor > Eclipse
view src/sample/merge/TranslaterImp1.java @ 104:a2089a730a2e
change Translater class to interface.
author | kent |
---|---|
date | Sat, 22 Dec 2007 21:10:46 +0900 |
parents | |
children | 2e649cd44078 |
line wrap: on
line source
package sample.merge; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.Stack; import remoteeditor.command.REPCommand; import remoteeditor.network.REP; public class TranslaterImp1 implements Translater{ //List <REPCommand> userList; //List <REPCommand> tokenList; private LinkedList<REPCommand> sentCmds; //private LinkedList<REPCommand> unMergedCmds; private Stack<REPCommand> unMergedCmds; public int eid; public TranslaterImp1(int _eid){ eid = _eid; sentCmds = new LinkedList<REPCommand>(); unMergedCmds = new Stack<REPCommand>(); } /** * Translate cmd When the editor send REPCommand. * but now, Only adding cmd to the queue is available. * @param cmd * @return translated command. */ public REPCommand transSendCmd(REPCommand cmd){ sentCmds.add(cmd); unMergedCmds.push(cmd); return cmd; } /** * Dequeue command cmd that was returned. * @param cmd */ public REPCommand[] catchOwnCommand(REPCommand cmd){ ArrayList<REPCommand> returnCmds = new ArrayList<REPCommand>(); ArrayList<REPCommand> cmds = new ArrayList<REPCommand>(); // ringである以上、戻ってきたコマンドは確実にキューsentCmdsの先頭にある事を期待している //REPCommand cmd0 = sentCmds.poll(); //assert cmd0.seq!=cmd.seq; assert cmd.eid==eid; /* スタックから全部取り出してマージする まだマージできないやつはまたスタックへ戻す */ while ( !unMergedCmds.isEmpty() ){ REPCommand cmd0 = unMergedCmds.pop(); returnCmds.add( createUndo(cmd0) ); cmds.add(cmd0); } //if (cmds.size()==0) return null; returnCmds.addAll( sortCmds(cmds) ); return returnCmds.toArray(new REPCommand[0]); } private REPCommand createUndo(REPCommand cmd){ //REPCommand retCmd = cmd.clone(); REPCommand retCmd = new REPCommand(cmd.cmd, cmd.sid, cmd.eid, cmd.seq, cmd.lineno, cmd.string.length(), cmd.string); if (cmd.cmd==REP.REPCMD_INSERT) retCmd.cmd=REP.REPCMD_DELETE; else if (cmd.cmd==REP.REPCMD_DELETE) retCmd.cmd=REP.REPCMD_INSERT; return retCmd; } private ArrayList<REPCommand> sortCmds(ArrayList<REPCommand> cmds) { ArrayList<REPCommand> sortedCmds = new ArrayList<REPCommand>(); REPCommand cmd0; int prevEid=0; int i,j; /* EID,SEQの低い順に、各EID毎に1個だけ選択しcmdsに格納 */ while ( null != (cmd0=getPrecedence(cmds, prevEid+1)) ){ sortedCmds.add(cmd0); cmds.remove(cmd0); prevEid = cmd0.eid; } /* lineno の大きい順にソート */ for (i=0; i<sortedCmds.size(); i++){ int k=i; for (j=i+1; j<sortedCmds.size(); j++){ if ( sortedCmds.get(k).lineno > sortedCmds.get(j).lineno ) continue; else if ( sortedCmds.get(k).lineno < sortedCmds.get(j).lineno || sortedCmds.get(k).eid > sortedCmds.get(j).eid ) /* deleteとinsertの場合などはeidによらず、順序を強制する必要があるかも */ k=j; } cmd0 = sortedCmds.get(i); sortedCmds.set(i, sortedCmds.get(k)); sortedCmds.set(k, cmd0); } return sortedCmds; } /* search cmd. ordering by min EID that is lower lowEid and min SEQ. */ private REPCommand getPrecedence(ArrayList<REPCommand> cmds, int lowEid) { int cEid, cSeq; cEid=cSeq=Integer.MAX_VALUE; REPCommand ret=null; for (int i=0; i<cmds.size(); i++){ REPCommand tmp = cmds.get(i); if ( tmp.eid<lowEid ) continue; else if ( tmp.eid>cEid ) continue; else if ( tmp.eid==cEid ) { if ( tmp.seq>cSeq ) continue; cSeq=tmp.seq; ret = tmp; } else { /* tmp.eid<cEid */ cEid = tmp.eid; cSeq = tmp.seq; ret = tmp; } //if ( cEid>cmds.get(i) && cmds.get(i)>lowEid ) } return ret; } /** * Translate Command cmd that was received from SeMa. * @param cmd the command to be translated. * @return translated commannd. */ public REPCommand[] transReceiveCmd(REPCommand cmd){ int i=0; REPCommand cmds[]; if (cmd.eid==eid){ return catchOwnCommand(cmd); } for (REPCommand cmd0 : unMergedCmds){ if (cmd0.eid==cmd.eid) i++; } if ( sentCmds.size()<i ){ cmds = new REPCommand[2]; String str = "NO OPERATION"; cmds[0] = new REPCommand(REP.REPCMD_NOP, 0, eid, 0, 0, str.length(), str); cmds[1] = cmd; //unMergedCmds.push(cmds[0]); unMergedCmds.push(cmd); sentCmds.add(cmds[0]); return cmds; } unMergedCmds.push(cmd); /* but.. */ cmds = new REPCommand[1]; cmds[0] = cmd; return cmds; } public void setEid(int _eid){ eid = _eid; } }