Mercurial > hg > RemoteEditor > Eclipse
changeset 104:a2089a730a2e
change Translater class to interface.
author | kent |
---|---|
date | Sat, 22 Dec 2007 21:10:46 +0900 |
parents | dca742322984 |
children | 6c209de0dd99 |
files | src/sample/merge/Translater.java src/sample/merge/TranslaterImp0.java src/sample/merge/TranslaterImp1.java |
diffstat | 3 files changed, 347 insertions(+), 154 deletions(-) [+] |
line wrap: on
line diff
--- a/src/sample/merge/Translater.java Sat Dec 22 19:05:12 2007 +0900 +++ b/src/sample/merge/Translater.java Sat Dec 22 21:10:46 2007 +0900 @@ -1,169 +1,33 @@ package sample.merge; -import java.util.LinkedList; - import remoteeditor.command.REPCommand; -import remoteeditor.network.REP; -public class Translater { - //List <REPCommand> userList; - //List <REPCommand> tokenList; - private LinkedList<REPCommand> cmdList; - public int eid; - - public Translater(int _eid){ - eid = _eid; - cmdList = new LinkedList<REPCommand>(); - } +public interface Translater { /** - * Translate cmd When the editor send REPCommand. - * but now, Only adding cmd to the queue is available. - * @param cmd - * @return translated command. + * Translate command When the editor send REPCommand to remote editor. + * @param command which the editor want to send. + * @return translated command which should be sent by the editor. */ - public REPCommand transSendCmd(REPCommand cmd){ - cmdList.add(cmd); - return cmd; - } + abstract public REPCommand transSendCmd(REPCommand cmd); + /** - * Dequeue command cmd that was returned. - * @param cmd + * Inform translater about that the editor receive own command which it sent. + * but in this case, you can use also transReceiveCmd() + * @param command which the editor sent. */ - public void catchOwnCommand(REPCommand cmd){ - // ringである以上、戻ってきたコマンドは確実にキューの先頭にある事を期待している - REPCommand cmd0 = cmdList.poll(); - assert cmd.eid==eid; - assert cmd0.seq!=cmd.seq; - // とりあえず今のところは何もしない事になっている - } + abstract public REPCommand[] catchOwnCommand(REPCommand cmd); + /** * Translate Command cmd that was received from SeMa. * @param cmd the command to be translated. - * @return translated commannd. + * @return translated command. */ - public REPCommand transReceiveCmd(REPCommand cmd){ - if (cmd.eid==eid){ - catchOwnCommand(cmd); - return null; - } - // 拡張for構文、順序は保証されるの? 保証されないとダメ。 - for(REPCommand cmd0: cmdList){ - if (cmd0.lineno>cmd.lineno) continue; - else if (cmd0.lineno==cmd.lineno){ - // 既に送ったCommandと行番号が重なる限り、繰り返し変換する - cmd = translate(cmd, cmd0); - } - // ずれたlinenoを合わせる - else if (cmd0.cmd==REP.REPCMD_INSERT) cmd.lineno++; - else if (cmd0.cmd==REP.REPCMD_DELETE) cmd.lineno--; - } - return cmd; - } - - /* - * - * 比較時に行番号が重なったときの処理は以下の表。 - * なるべくテキストが残るようにしている。 - * 0 -- なにもしない - * +1 -- 行番号を +1 - * INS -- コマンド id を 'REPCMD_INSERT' にする。 - * NOP -- コマンドをNOP(何もしない)にする。 - * ?* -- TOKENがMasterを通っていなければ - * REMOTE - * | i | r | d - * ---|------------------ - * U i | +1* | +1 | +1 - * S ---|------------------ - * E r | 0 | NOP*| NOP - * R ---|------------------ - * d | 0 | INS | NOP - * - * - */ - private REPCommand translate(REPCommand Rcmd, REPCommand Lcmd){ - assert Rcmd.lineno==Lcmd.lineno; - int Lird = Lcmd.cmd; - int Rird = Rcmd.cmd; + abstract public REPCommand[] transReceiveCmd(REPCommand cmd); - if (Lird==REP.REPCMD_INSERT){ - if (Rird==REP.REPCMD_INSERT){ - if (!Rcmd.throughMaster) Rcmd.lineno++; - }else if (Rird==REP.REPCMD_REPLACE){ - Rcmd.lineno++; - }else if (Rird==REP.REPCMD_DELETE){ - Rcmd.lineno++; - } - }else if (Lird==REP.REPCMD_REPLACE){ - if (Rird==REP.REPCMD_INSERT){ - }else if (Rird==REP.REPCMD_REPLACE){ - if (!Rcmd.throughMaster) Rcmd.cmd=REP.REPCMD_NOP; - }else if (Rird==REP.REPCMD_DELETE){ - Rcmd.cmd = REP.REPCMD_NOP; - } - }else if (Lird==REP.REPCMD_DELETE){ - if (Rird==REP.REPCMD_INSERT){ - }else if (Rird==REP.REPCMD_REPLACE){ - Rcmd.cmd = REP.REPCMD_INSERT; - }else if (Rird==REP.REPCMD_DELETE){ - Rcmd.cmd = REP.REPCMD_NOP; - } - } - - return Rcmd; - -/* - // あとで整形しよう - if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_INSERT){ - if (!Rcmd.throughMaster) Rcmd.lineno++; - } - if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_DELETE){ - Rcmd.cmd = REP.REPCMD_NOP; - } - if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_REPLACE){ - if (!Rcmd.throughMaster) Rcmd.cmd=REP.REPCMD_NOP; - } - - if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_DELETE){ - Rcmd.lineno++; - } - if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_INSERT){ - } - - if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_DELETE){ - Rcmd.cmd = REP.REPCMD_NOP; - } - if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_REPLACE){ - Rcmd.cmd = REP.REPCMD_INSERT; - } - - if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_REPLACE){ - Rcmd.lineno++; - } - if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_INSERT){ - } - return Rcmd; -*/ - } - - public void setEid(int _eid){ - eid = _eid; - } - - /* - old version ( not ring type) - 0 -- なにもしない - +1 -- 行番号を +1 - i -- コマンド id を 'i' にする。 - X -- コマンドを削除(無視に)する。 - - USER - | i | r | d - ---|-------------------- - T i | 0\+1 | 0\+1 | 0\+1 - O ---|-------------------- - K r | +1\0 | 0\X | i\X - E ---|-------------------- - N d | +1\0 | X\i | X\X - */ + /** + * set the editor's id. + * @param editor's id. + */ + abstract public void setEid(int _eid); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sample/merge/TranslaterImp0.java Sat Dec 22 21:10:46 2007 +0900 @@ -0,0 +1,172 @@ +package sample.merge; + +import java.util.LinkedList; + +import remoteeditor.command.REPCommand; +import remoteeditor.network.REP; + +public class TranslaterImp0 implements Translater{ + //List <REPCommand> userList; + //List <REPCommand> tokenList; + private LinkedList<REPCommand> cmdList; + public int eid; + + public TranslaterImp0(int _eid){ + eid = _eid; + cmdList = new LinkedList<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){ + cmdList.add(cmd); + return cmd; + } + /** + * Dequeue command cmd that was returned. + * @param cmd + */ + public REPCommand[] catchOwnCommand(REPCommand cmd){ + // ring縺ァ縺ゅk莉・荳翫∵綾縺」縺ヲ縺阪◆繧ウ繝槭Φ繝峨ッ遒コ螳溘↓繧ュ繝・繝シ縺ョ蜈磯ュ縺ォ縺ゅk莠九r譛溷セ縺励※縺繧 + REPCommand cmd0 = cmdList.poll(); + assert cmd.eid==eid; + assert cmd0.seq!=cmd.seq; + // 縺ィ繧翫≠縺医★莉翫ョ縺ィ縺薙m縺ッ菴輔b縺励↑縺莠九↓縺ェ縺」縺ヲ縺繧 + return null; + } + /** + * Translate Command cmd that was received from SeMa. + * @param cmd the command to be translated. + * @return translated commannd. + */ + public REPCommand[] transReceiveCmd(REPCommand cmd){ + REPCommand cmds[]; + if (cmd.eid==eid){ + return catchOwnCommand(cmd); + } + // 諡。蠑オfor讒区枚縲鬆蠎上ッ菫晁ィシ縺輔l繧九ョ? 菫晁ィシ縺輔l縺ェ縺縺ィ繝繝。縲 + for(REPCommand cmd0: cmdList){ + if (cmd0.lineno>cmd.lineno) continue; + else if (cmd0.lineno==cmd.lineno){ + // 譌「縺ォ騾√▲縺櫃ommand縺ィ陦檎分蜿キ縺碁阪↑繧矩剞繧翫∫ケー繧願ソ斐@螟画鋤縺吶k + cmd = translate(cmd, cmd0); + } + // 縺壹l縺殕ineno繧貞粋繧上○繧 + else if (cmd0.cmd==REP.REPCMD_INSERT) cmd.lineno++; + else if (cmd0.cmd==REP.REPCMD_DELETE) cmd.lineno--; + } + cmds = new REPCommand[1]; + cmds[0] = cmd; + return cmds; + } + + /* + * + * 豈碑シ譎ゅ↓陦檎分蜿キ縺碁阪↑縺」縺溘→縺阪ョ蜃ヲ逅縺ッ莉・荳九ョ陦ィ縲 + * 縺ェ繧九∋縺上ユ繧ュ繧ケ繝医′谿九k繧医≧縺ォ縺励※縺繧九 + * 0 -- 縺ェ縺ォ繧ゅ@縺ェ縺 + * +1 -- 陦檎分蜿キ繧 +1 + * INS -- 繧ウ繝槭Φ繝 id 繧 'REPCMD_INSERT' 縺ォ縺吶k縲 + * NOP -- 繧ウ繝槭Φ繝峨rNOP(菴輔b縺励↑縺)縺ォ縺吶k縲 + * ?* -- TOKEN縺勲aster繧帝壹▲縺ヲ縺縺ェ縺代l縺ー + * REMOTE + * | i | r | d + * ---|------------------ + * U i | +1* | +1 | +1 + * S ---|------------------ + * E r | 0 | NOP*| NOP + * R ---|------------------ + * d | 0 | INS | NOP + * + * + */ + private REPCommand translate(REPCommand Rcmd, REPCommand Lcmd){ + assert Rcmd.lineno==Lcmd.lineno; + int Lird = Lcmd.cmd; + int Rird = Rcmd.cmd; + + if (Lird==REP.REPCMD_INSERT){ + if (Rird==REP.REPCMD_INSERT){ + if (!Rcmd.throughMaster) Rcmd.lineno++; + }else if (Rird==REP.REPCMD_REPLACE){ + Rcmd.lineno++; + }else if (Rird==REP.REPCMD_DELETE){ + Rcmd.lineno++; + } + }else if (Lird==REP.REPCMD_REPLACE){ + if (Rird==REP.REPCMD_INSERT){ + }else if (Rird==REP.REPCMD_REPLACE){ + if (!Rcmd.throughMaster) Rcmd.cmd=REP.REPCMD_NOP; + }else if (Rird==REP.REPCMD_DELETE){ + Rcmd.cmd = REP.REPCMD_NOP; + } + }else if (Lird==REP.REPCMD_DELETE){ + if (Rird==REP.REPCMD_INSERT){ + }else if (Rird==REP.REPCMD_REPLACE){ + Rcmd.cmd = REP.REPCMD_INSERT; + }else if (Rird==REP.REPCMD_DELETE){ + Rcmd.cmd = REP.REPCMD_NOP; + } + } + + return Rcmd; + +/* + // 縺ゅ→縺ァ謨エ蠖「縺励h縺 + if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_INSERT){ + if (!Rcmd.throughMaster) Rcmd.lineno++; + } + if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_DELETE){ + Rcmd.cmd = REP.REPCMD_NOP; + } + if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_REPLACE){ + if (!Rcmd.throughMaster) Rcmd.cmd=REP.REPCMD_NOP; + } + + if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_DELETE){ + Rcmd.lineno++; + } + if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_INSERT){ + } + + if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_DELETE){ + Rcmd.cmd = REP.REPCMD_NOP; + } + if (Lcmd.cmd==REP.REPCMD_DELETE && Rcmd.cmd==REP.REPCMD_REPLACE){ + Rcmd.cmd = REP.REPCMD_INSERT; + } + + if (Lcmd.cmd==REP.REPCMD_INSERT && Rcmd.cmd==REP.REPCMD_REPLACE){ + Rcmd.lineno++; + } + if (Lcmd.cmd==REP.REPCMD_REPLACE && Rcmd.cmd==REP.REPCMD_INSERT){ + } + return Rcmd; +*/ + } + + public void setEid(int _eid){ + eid = _eid; + } + + /* + old version ( not ring type) + 0 -- 縺ェ縺ォ繧ゅ@縺ェ縺 + +1 -- 陦檎分蜿キ繧 +1 + i -- 繧ウ繝槭Φ繝 id 繧 'i' 縺ォ縺吶k縲 + X -- 繧ウ繝槭Φ繝峨r蜑企勁(辟。隕悶↓)縺吶k縲 + + USER + | i | r | d + ---|-------------------- + T i | 0ツ・+1 | 0ツ・+1 | 0ツ・+1 + O ---|-------------------- + K r | +1ツ・0 | 0ツ・X | iツ・X + E ---|-------------------- + N d | +1ツ・0 | Xツ・i | Xツ・X + */ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sample/merge/TranslaterImp1.java Sat Dec 22 21:10:46 2007 +0900 @@ -0,0 +1,157 @@ +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縺ァ縺ゅk莉・荳翫∵綾縺」縺ヲ縺阪◆繧ウ繝槭Φ繝峨ッ遒コ螳溘↓繧ュ繝・繝シsentCmds縺ョ蜈磯ュ縺ォ縺ゅk莠九r譛溷セ縺励※縺繧 + //REPCommand cmd0 = sentCmds.poll(); + //assert cmd0.seq!=cmd.seq; + assert cmd.eid==eid; + + /* 繧ケ繧ソ繝繧ッ縺九i蜈ィ驛ィ蜿悶j蜃コ縺励※繝槭シ繧ク縺吶k 縺セ縺繝槭シ繧ク縺ァ縺阪↑縺繧縺、縺ッ縺セ縺溘せ繧ソ繝繧ッ縺ク謌サ縺 */ + 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縺ォ繧医i縺壹鬆蠎上r蠑キ蛻カ縺吶k蠢隕√′縺ゅk縺九b */ + 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; + } +}