Mercurial > hg > RemoteEditor > REPSessionManager
changeset 324:e235998427a6 before-merge-fix
try to fix merger
author | kono |
---|---|
date | Sat, 11 Oct 2008 16:31:03 +0900 |
parents | 1e605880d49e |
children | be0831086e63 |
files | rep/Editor.java rep/EditorPlus.java rep/SessionManager.java rep/translater/Translate.java rep/translater/Translater.java rep/translater/TranslaterImp1.java rep/translator/Translate.java rep/translator/Translator.java rep/translator/TranslatorImpl.java |
diffstat | 9 files changed, 445 insertions(+), 440 deletions(-) [+] |
line wrap: on
line diff
--- a/rep/Editor.java Fri Oct 10 18:04:09 2008 +0900 +++ b/rep/Editor.java Sat Oct 11 16:31:03 2008 +0900 @@ -5,11 +5,11 @@ import rep.channel.REPSocketChannel; import rep.handler.PacketSet; import rep.optimizers.*; -import rep.translater.TranslaterImp1; +import rep.translator.TranslatorImpl; public class Editor extends Forwarder { - private TranslaterImp1 translater; + private TranslatorImpl translator; private List<REPCommand> sentList = new LinkedList<REPCommand>(); // REPCommands we are going to send to the next editor private REPCommandOptimizer optimizer; @@ -21,7 +21,7 @@ super(manager); this.manager = manager; eid = editorNo; - translater = new TranslaterImp1(eid); + translator = new TranslatorImpl(eid); if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ else optimizer = new NullOptimizer(); //なにもしないけどOptimizer. @@ -33,9 +33,9 @@ setHostAndPort(channel); } - public void translate(Forwarder nextEditor, REPCommand command){ + public void translate(Editor nextEditor, REPCommand command){ if(command.eid == nextEditor.getEID()){ - if(checkReturnedCommand(command)){ + if(nextEditor.checkReturnedCommand(command)){ // エディタからのコマンドが元のエディタに戻ってきた // START_MERGE を送る REPCommand cmd = new REPCommand(REP.SMCMD_START_MERGE,command.sid,REP.SM_EID.id,seq(),0,""); @@ -43,31 +43,30 @@ // Session Manager 側で、このeditorへの他のeditorからの // 入力を止めて、merge にそなえる。merge は、eidtor 側から // ACKが来てから始まる。 - translater.startMerge(cmd); + translator.startMerge(cmd); return; } else assert(false); } else if(command.eid == eid){ //エディタからの新たな編集コマンド sentList.add(command); assert(sentList.size()<limit); - translater.transSendCmd(command); + translator.transSendCmd(command); nextEditor.send(command); return; }else if(command.eid == REP.MERGE_EID.id){ //マージコマンドが返ってきた - if(translater.checkMergeConflict(command)){ + if(translator.checkMergeConflict(command)){ //マージ中にエディタからの割り込みがあった場合 - if (optimizedSend(translater.getMergeAgain())) { + if (optimizedSend(translator.getMergeAgain())) { + endMerge(); return; } - } - if(!isMerging()) { + } else endMerge(); - } }else{ //他のエディタからの編集コマンド if(!isMerging()) { - translater.transReceiveCmd(nextEditor,command); + translator.transReceiveCmd(nextEditor,command); return; } manager.addWaitingCommand(new PacketSet(getChannel(), this, command)); @@ -76,11 +75,11 @@ } boolean merge(REPCommand command) { - REPCommand prev = translater.prev(); + REPCommand prev = translator.prev(); if(prev==null) return false; assert(prev.eid==command.eid); //マージして送信 - return translater.catchOwnCommand(this); + return translator.catchOwnCommand(this); } boolean checkReturnedCommand(REPCommand command) { @@ -93,7 +92,7 @@ } return true; }else{ - System.err.println("Editor.checkReturnedCommand() : command = " + command); + System.out.println("Editor.checkReturnedCommand() : command = " + command); assert(false); } } @@ -122,7 +121,7 @@ @Override public void setEID(int eid) { this.eid = eid; - translater.setEid(eid); + translator.setEid(eid); } public String toString(){ @@ -130,14 +129,9 @@ } public boolean isMerging() { - return translater.isMerging(); + return translator.isMerging(); } - public boolean hasSession() { - return sid != -1; - } - public void setSID(int sessionID) { - sid = sessionID; - } + /** * Sent optimized merged command list @@ -157,8 +151,10 @@ } void endMerge() { + if(translator.isMerging()) return; REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,eid,sid,seq(),0,""); send(mergeEnd); + translator.endMerge(); } @Override @@ -171,14 +167,14 @@ case REPCMD_INSERT: case REPCMD_NOP: { - translate(next, receivedCommand); + translate((Editor)next, receivedCommand); break; } case SMCMD_START_MERGE_ACK: { // マージの処理と次のエディタへコマンドを送信する処理 - translater.mergeAck(); + translator.mergeAck(); if (!merge(receivedCommand)) { // nothing to do, send END_MERGE endMerge();
--- a/rep/EditorPlus.java Fri Oct 10 18:04:09 2008 +0900 +++ b/rep/EditorPlus.java Sat Oct 11 16:31:03 2008 +0900 @@ -35,6 +35,10 @@ public int getSID() { return sid; } + + public boolean hasSession() { + return sid != -1; + } public String toString(){ return ("Editor:" + eid);
--- a/rep/SessionManager.java Fri Oct 10 18:04:09 2008 +0900 +++ b/rep/SessionManager.java Sat Oct 11 16:31:03 2008 +0900 @@ -205,6 +205,7 @@ if (sessionManagerCommand(channel, receivedCommand)) return; Session s = getSession(receivedCommand.sid); Editor e = s.getEditor(channel); + // if(e==null) throw new IOException(); e.manage(receivedCommand); } @@ -547,9 +548,10 @@ System.out.println("SessionManager.selectSession():editor = " + editor); return; } + if (editor.hasSession()) return; REPSocketChannel<REPCommand> channel = editor.getChannel(); - System.out.println("SessionManager.session.hasOnwer="+session.hasOwner()); + // System.out.println("SessionManager.session.hasOnwer="+session.hasOwner()); if(session.hasOwner()){ editor.setEID(session.newEid()); editor.setSID(sid); @@ -611,7 +613,7 @@ public void addWriteQueue(PacketSet packetSet) { - writeQueue.add(packetSet); + writeQueue.addLast(packetSet); assert(writeQueue.size()<packetLimit) ; }
--- a/rep/translater/Translate.java Fri Oct 10 18:04:09 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -package rep.translater; - -import java.util.List; - -import rep.REPCommand; -import rep.REP; - -public class Translate { - List <REPCommand> userList; - List <REPCommand> tokenList; - private boolean REP_IGNORE = true; - public int myeid; - - public Translate(){ - - } - - //public Translate(List<REPCommand> userList, List<REPCommand> tokenList){ - // this.userList = userList; - // this.tokenList = tokenList; - //merge(); - //} - - - - public Translate(List<REPCommand> userCmdList, List<REPCommand> tokenCmdList) { - this.userList = userCmdList; - this.tokenList = tokenCmdList; - } - - public void addUserList(REPCommand usercmd){ - userList.add(usercmd); - } - public void addTokenList(REPCommand tokencmd){ - if(tokencmd.eid == myeid){ - tokenList.clear(); - userList.remove(0); - }else{ - tokenList.add(tokencmd); - } - } - - void merge(){ - REPCommand h_pricmd; - REPCommand l_pricmd; -// Iterator userListIterator = userList.iterator(); -// while(userListIterator.hasNext()){ - for(REPCommand userCmd:userList){ - //Iterator tokenListIterator = tokenList.iterator(); - //Rep_Cmd userCmd = (Rep_Cmd)userListIterator.next(); - if(userCmd.stat) continue; /* �폜�����(�\��)��REP�R�}���h�̔�r�͖��� */ - //while(tokenListIterator.hasNext()){ - for(REPCommand tokenCmd:tokenList){ -// Rep_Cmd tokenCmd =(Rep_Cmd)tokenListIterator.next(); - if(tokenCmd.eid == myeid) { - if(tokenCmd.seq == userCmd.seq){ - tokenCmd.stat = REP_IGNORE; - userCmd.stat = REP_IGNORE; - } - } - if(tokenCmd.stat == REP_IGNORE) continue; /* �폜�����(�\��)��REP�R�}���h�̔�r�͖��� */ - if(userCmd.stat == REP_IGNORE) break; - if(userCmd.lineno < tokenCmd.lineno) { /* UsersLineNumber < TokensLineNumber */ - if(userCmd.cmd == REP.REPCMD_INSERT){ - tokenCmd.lineno++; - }else if(userCmd.cmd == REP.REPCMD_DELETE){ - tokenCmd.lineno--; - } - }else if(userCmd.lineno > tokenCmd.lineno){ /* UsersLineNumber > TokensLineNumber */ - if(tokenCmd.cmd == REP.REPCMD_INSERT){ - userCmd.lineno++; - }else if(tokenCmd.cmd == REP.REPCMD_DELETE){ - userCmd.lineno--; - } - }else if(userCmd.lineno == tokenCmd.lineno){ /* UsersLineNumber == TokensLineNumber */ - /* - * �s�ԍ����d�Ȃ��REP�R�}���h�̋������N����̂ŁA - * �ǂ��炩�����Ȃ��Ƃ����Ȃ��B - * uid �����������D��(h_pricmd��)���A - * uid ���傫����(l_pricmd)��ύX����B - */ - if(userCmd.eid < tokenCmd.eid){ - h_pricmd = userCmd; - l_pricmd = tokenCmd; - }else { - h_pricmd = tokenCmd; - l_pricmd = userCmd; - } - if(h_pricmd.cmd == REP.REPCMD_INSERT){ - l_pricmd.lineno++; - }else if(l_pricmd.cmd == REP.REPCMD_REPLACE){ - if(l_pricmd.cmd == REP.REPCMD_INSERT){ - /* h_pricmd ���D�悳��,l_pricmd �͍폜(������)���� */ - l_pricmd.stat = REP_IGNORE; - }else if(l_pricmd.cmd == REP.REPCMD_DELETE){ - /* - * l_pricmd ���ł͂��ł�delete����Ă���̂ŁA - * h_pricmd �� REP_REPLACE_CMD -> REP_INSERT_CMD �֕ύX�B - */ - h_pricmd.cmd = REP.REPCMD_INSERT; - l_pricmd.stat = REP_IGNORE; - } - }else if(h_pricmd.cmd == REP.REPCMD_DELETE){ - if (l_pricmd.cmd == REP.REPCMD_INSERT) { - h_pricmd.lineno++; - } else if(l_pricmd.cmd == REP.REPCMD_REPLACE){ - /* - * h_pricmd ���ł͂��ł�delete����Ă���̂ŁA - * l_pricmd ���� REP_REPLACE_CMD -> REP_INSERT_CMD �֕ύX�B - */ - l_pricmd.cmd = REP.REPCMD_INSERT; - h_pricmd.stat= REP_IGNORE; - } else { /* l_pricmd->cmd == REP_DELETE_LINE_CMD */ - /* - * ����ƍ폜����s���d�Ȃ�̂ŁA - * ����̃R�}���h���ɂ���B - * �����ł͂��łɂ��̍s�͍폜����Ă���B - */ - h_pricmd.stat = REP_IGNORE; - l_pricmd.stat = REP_IGNORE; - break; - } - } - } - } - } -// Iterator userListIterator = userList.iterator(); -// while(userListIterator.hasNext()){ -// //Iterator tokenListIterator = tokenList.iterator(); -// REPCommand userCmd = (REPCommand)userListIterator.next(); -// if(userCmd.stat == REP_IGNORE){ -// userListIterator.remove(); -// } -// } -// -// Iterator tokenListIterator = tokenList.iterator(); -// while(tokenListIterator.hasNext()){ -// REPCommand tokenCmd = (REPCommand)tokenListIterator.next(); -// if(tokenCmd.stat == REP_IGNORE){ -// tokenListIterator.remove(); -// } -// } - } - - public void setMyEID(int myeid2) { - // TODO Auto-generated method stub - myeid = myeid2; - } -}
--- a/rep/translater/Translater.java Fri Oct 10 18:04:09 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -package rep.translater; - -import rep.Editor; -import rep.Forwarder; -import rep.REPCommand; - -public interface Translater { - - /** - * 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. - */ - abstract public REPCommand transSendCmd(REPCommand 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. - */ - abstract public boolean catchOwnCommand(Editor editor); - - /** - * Translate Command cmd that was received from SeMa. - * @param cmd the command to be translated. - * @return translated command. - */ - abstract public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd); - - /** - * set the editor's id. - * @param editor's id. - */ - abstract public void setEid(int _eid); -}
--- a/rep/translater/TranslaterImp1.java Fri Oct 10 18:04:09 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -package rep.translater; - -import java.util.Collection; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.Stack; -import java.util.TreeSet; - -import rep.Editor; -import rep.Forwarder; -import rep.REPCommand; -import rep.REP; - -public class TranslaterImp1 implements Translater{ - public int eid; - /* - * queue が5つもいるって、あまりに馬鹿げてる。 - */ - private LinkedList<REPCommand> sentCmds; - private Stack<REPCommand> unMergedCmds; - private LinkedList<REPCommand> undoReplaceList; - private LinkedList<REPCommand> sentMergedList; - private LinkedList<REPCommand> mergeAgainList; - - public TranslaterImp1(int _eid){ - eid = _eid; - sentCmds = new LinkedList<REPCommand>(); - unMergedCmds = new Stack<REPCommand>(); - undoReplaceList = new LinkedList<REPCommand>(); - mergeAgainList = new LinkedList<REPCommand>(); - sentMergedList = new LinkedList<REPCommand>(); - } - - /** - * New command from an editor - * The command is sent to the next editor - * @param cmd - * @return translated command. - */ - public REPCommand transSendCmd(REPCommand cmd){ - sentCmds.add(cmd); - unMergedCmds.push(cmd); - - //マージ中にユーザから割り込みがあった場合 - if(isMerging()){ - mergeAgainList.add(cmd); - } - - return cmd; - } - /** - * My command is returned from the session ring. At this - * stage writeQueue is empty, our editor is waiting for me. - * Start merge process. - * @param cmd - */ - public boolean catchOwnCommand(Editor editor){ - LinkedList<REPCommand> output = new LinkedList<REPCommand>(); - LinkedList<REPCommand> cmds = new LinkedList<REPCommand>(); - //スタック上にあるコマンドを全部undoコマンドにする - while ( !unMergedCmds.isEmpty() ){ - REPCommand cmd0 = unMergedCmds.pop(); - output.add( createUndo(cmd0) ); - cmds.add(cmd0); - } - - /* 必要な分だけソートして返却用のリストに追加 */ - output.addAll( sortCmds(cmds) ); - - /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ - output.addAll(cmds); - for(REPCommand c: cmds) { - output.add(c); - unMergedCmds.push(c); - } - return editor.optimizedSend(output); - } - - public REPCommand prev() { - return sentCmds.poll(); - } - - private REPCommand createUndo(REPCommand cmd){ - REPCommand retCmd = new REPCommand(cmd); - 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; - } - - class REPCommandComparator implements Comparator<REPCommand>{ - - public int compare(REPCommand o1, REPCommand o2) { - - if ( o2.lineno > o1.lineno ) return 1; - else if ( o2.lineno < o1.lineno - || o2.eid > o1.eid ) - return -1; - - return 1; - } - - } - - private Collection<REPCommand> sortCmds(LinkedList<REPCommand> cmds) { - TreeSet<REPCommand> sortedCmds1 = new TreeSet<REPCommand>(new REPCommandComparator()); - int top; - int prevEid=-1; - while ( -1 != (top=getPrecedence(cmds, prevEid+1)) ){ - REPCommand tmp = cmds.remove(top); - sortedCmds1.add(tmp); - prevEid = tmp.eid; - } - - return sortedCmds1; - } - - /* search cmd. ordering by min EID that is lower lowEid and min SEQ. */ - private int getPrecedence(LinkedList<REPCommand> cmds, int lowEid) { - int cEid, cSeq; - cEid=cSeq=Integer.MAX_VALUE; - int ret=-1; - for (int i=0; i<cmds.size(); i++){ - REPCommand c = cmds.get(i); - if ( c.eid<lowEid ) continue; - else if ( c.eid>cEid ) continue; - else if ( c.eid==cEid ) { - if ( c.seq>cSeq ) continue; - cSeq=c.seq; - ret = i; - } else { /* tmp.eid<cEid */ - cEid = c.eid; - cSeq = c.seq; - ret = i; - } - } - return ret; - } - - /** - * Translate Command cmd that was received from SeMa. - * @param cmd the command to be translated. - * @return translated commannd. - */ - public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd){ - assert (cmd.eid != eid); - // nop command の挿入は Editor 側で行って、こちら側ではやらない - unMergedCmds.push(cmd); - nextEditor.send(cmd); - } - - public void setEid(int _eid){ - eid = _eid; - } - - public Stack<REPCommand> getList() { - // TODO Auto-generated method stub - return unMergedCmds; - } - - public LinkedList<REPCommand> getSentCmds() { - // TODO Auto-generated method stub - return sentCmds; - } - - public void setUndoCommand(REPCommand command) { - // TODO Auto-generated method stub - undoReplaceList.add(command); - } - - public boolean checkMergeConflict(REPCommand command) { - // sentMergedList.remove(); - - if(mergeAgainList.size() > 0){ - mergeAgainList.add(command); - if(sentMergedList.size() == 0){ - return true; - } - } - - return false; - } - - public LinkedList<REPCommand> getMergeAgain() { - LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>(); - for(int i = 0; i < mergeAgainList.size(); i++){ - //eid = REP.MEGE_EID - returnCommand.add(createUndo(mergeAgainList.get(mergeAgainList.size() - i -1))); - } - for(REPCommand command : mergeAgainList){ - if(command.eid == REP.MERGE_EID.id){ - returnCommand.add(command); - } - } - for(REPCommand command : mergeAgainList){ - if(command.eid == eid){ - command.eid = REP.MERGE_EID.id; - returnCommand.add(command); - } - } - mergeAgainList.clear(); - sentMergedList = returnCommand; - return returnCommand; - } - - public boolean isFinished() { - if(unMergedCmds.size() > 0) return false; - if(sentMergedList.size() > 0) return false; - if(sentCmds.size() > 0) return false; - return true; - } - - public boolean isMerging() { - if(sentMergedList.size() > 0) return true; - return false; - } - - public void startMerge(REPCommand cmd) { - sentMergedList.add(cmd); - - } - - public void mergeAck() { - sentMergedList.remove(); - } - - - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/translator/Translate.java Sat Oct 11 16:31:03 2008 +0900 @@ -0,0 +1,149 @@ +package rep.translator; + +import java.util.List; + +import rep.REPCommand; +import rep.REP; + +public class Translate { + List <REPCommand> userList; + List <REPCommand> tokenList; + private boolean REP_IGNORE = true; + public int myeid; + + public Translate(){ + + } + + //public Translate(List<REPCommand> userList, List<REPCommand> tokenList){ + // this.userList = userList; + // this.tokenList = tokenList; + //merge(); + //} + + + + public Translate(List<REPCommand> userCmdList, List<REPCommand> tokenCmdList) { + this.userList = userCmdList; + this.tokenList = tokenCmdList; + } + + public void addUserList(REPCommand usercmd){ + userList.add(usercmd); + } + public void addTokenList(REPCommand tokencmd){ + if(tokencmd.eid == myeid){ + tokenList.clear(); + userList.remove(0); + }else{ + tokenList.add(tokencmd); + } + } + + void merge(){ + REPCommand h_pricmd; + REPCommand l_pricmd; +// Iterator userListIterator = userList.iterator(); +// while(userListIterator.hasNext()){ + for(REPCommand userCmd:userList){ + //Iterator tokenListIterator = tokenList.iterator(); + //Rep_Cmd userCmd = (Rep_Cmd)userListIterator.next(); + if(userCmd.stat) continue; /* �폜�����(�\��)��REP�R�}���h�̔�r�͖��� */ + //while(tokenListIterator.hasNext()){ + for(REPCommand tokenCmd:tokenList){ +// Rep_Cmd tokenCmd =(Rep_Cmd)tokenListIterator.next(); + if(tokenCmd.eid == myeid) { + if(tokenCmd.seq == userCmd.seq){ + tokenCmd.stat = REP_IGNORE; + userCmd.stat = REP_IGNORE; + } + } + if(tokenCmd.stat == REP_IGNORE) continue; /* �폜�����(�\��)��REP�R�}���h�̔�r�͖��� */ + if(userCmd.stat == REP_IGNORE) break; + if(userCmd.lineno < tokenCmd.lineno) { /* UsersLineNumber < TokensLineNumber */ + if(userCmd.cmd == REP.REPCMD_INSERT){ + tokenCmd.lineno++; + }else if(userCmd.cmd == REP.REPCMD_DELETE){ + tokenCmd.lineno--; + } + }else if(userCmd.lineno > tokenCmd.lineno){ /* UsersLineNumber > TokensLineNumber */ + if(tokenCmd.cmd == REP.REPCMD_INSERT){ + userCmd.lineno++; + }else if(tokenCmd.cmd == REP.REPCMD_DELETE){ + userCmd.lineno--; + } + }else if(userCmd.lineno == tokenCmd.lineno){ /* UsersLineNumber == TokensLineNumber */ + /* + * �s�ԍ����d�Ȃ��REP�R�}���h�̋������N����̂ŁA + * �ǂ��炩�����Ȃ��Ƃ����Ȃ��B + * uid �����������D��(h_pricmd��)���A + * uid ���傫����(l_pricmd)��ύX����B + */ + if(userCmd.eid < tokenCmd.eid){ + h_pricmd = userCmd; + l_pricmd = tokenCmd; + }else { + h_pricmd = tokenCmd; + l_pricmd = userCmd; + } + if(h_pricmd.cmd == REP.REPCMD_INSERT){ + l_pricmd.lineno++; + }else if(l_pricmd.cmd == REP.REPCMD_REPLACE){ + if(l_pricmd.cmd == REP.REPCMD_INSERT){ + /* h_pricmd ���D�悳��,l_pricmd �͍폜(������)���� */ + l_pricmd.stat = REP_IGNORE; + }else if(l_pricmd.cmd == REP.REPCMD_DELETE){ + /* + * l_pricmd ���ł͂��ł�delete����Ă���̂ŁA + * h_pricmd �� REP_REPLACE_CMD -> REP_INSERT_CMD �֕ύX�B + */ + h_pricmd.cmd = REP.REPCMD_INSERT; + l_pricmd.stat = REP_IGNORE; + } + }else if(h_pricmd.cmd == REP.REPCMD_DELETE){ + if (l_pricmd.cmd == REP.REPCMD_INSERT) { + h_pricmd.lineno++; + } else if(l_pricmd.cmd == REP.REPCMD_REPLACE){ + /* + * h_pricmd ���ł͂��ł�delete����Ă���̂ŁA + * l_pricmd ���� REP_REPLACE_CMD -> REP_INSERT_CMD �֕ύX�B + */ + l_pricmd.cmd = REP.REPCMD_INSERT; + h_pricmd.stat= REP_IGNORE; + } else { /* l_pricmd->cmd == REP_DELETE_LINE_CMD */ + /* + * ����ƍ폜����s���d�Ȃ�̂ŁA + * ����̃R�}���h���ɂ���B + * �����ł͂��łɂ��̍s�͍폜����Ă���B + */ + h_pricmd.stat = REP_IGNORE; + l_pricmd.stat = REP_IGNORE; + break; + } + } + } + } + } +// Iterator userListIterator = userList.iterator(); +// while(userListIterator.hasNext()){ +// //Iterator tokenListIterator = tokenList.iterator(); +// REPCommand userCmd = (REPCommand)userListIterator.next(); +// if(userCmd.stat == REP_IGNORE){ +// userListIterator.remove(); +// } +// } +// +// Iterator tokenListIterator = tokenList.iterator(); +// while(tokenListIterator.hasNext()){ +// REPCommand tokenCmd = (REPCommand)tokenListIterator.next(); +// if(tokenCmd.stat == REP_IGNORE){ +// tokenListIterator.remove(); +// } +// } + } + + public void setMyEID(int myeid2) { + // TODO Auto-generated method stub + myeid = myeid2; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rep/translator/Translator.java Sat Oct 11 16:31:03 2008 +0900 @@ -0,0 +1,35 @@ +package rep.translator; + +import rep.Editor; +import rep.Forwarder; +import rep.REPCommand; + +public interface Translator { + + /** + * 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. + */ + abstract public REPCommand transSendCmd(REPCommand 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. + */ + abstract public boolean catchOwnCommand(Editor editor); + + /** + * Translate Command cmd that was received from SeMa. + * @param cmd the command to be translated. + * @return translated command. + */ + abstract public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd); + + /** + * 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/rep/translator/TranslatorImpl.java Sat Oct 11 16:31:03 2008 +0900 @@ -0,0 +1,231 @@ +package rep.translator; + +import java.util.Collection; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.Stack; +import java.util.TreeSet; + +import rep.Editor; +import rep.Forwarder; +import rep.REPCommand; +import rep.REP; + +public class TranslatorImpl implements Translator{ + public int eid; + /* + * queue が5つもいるって、あまりに馬鹿げてる。 + */ + private LinkedList<REPCommand> sentCmds; + private Stack<REPCommand> unMergedCmds; + private LinkedList<REPCommand> undoReplaceList; + public LinkedList<REPCommand> sentMergedList; + private LinkedList<REPCommand> mergeAgainList; + boolean merge_mode = false; + + public TranslatorImpl(int _eid){ + eid = _eid; + sentCmds = new LinkedList<REPCommand>(); + unMergedCmds = new Stack<REPCommand>(); + undoReplaceList = new LinkedList<REPCommand>(); + mergeAgainList = new LinkedList<REPCommand>(); + sentMergedList = new LinkedList<REPCommand>(); + } + + /** + * New command from an editor + * The command is sent to the next editor + * @param cmd + * @return translated command. + */ + public REPCommand transSendCmd(REPCommand cmd){ + sentCmds.add(cmd); + unMergedCmds.push(cmd); + + //マージ中にユーザから割り込みがあった場合 + if(isMerging()){ + mergeAgainList.add(cmd); + } + + return cmd; + } + /** + * My command is returned from the session ring. At this + * stage writeQueue is empty, our editor is waiting for me. + * Start merge process. + * @param cmd + */ + public boolean catchOwnCommand(Editor editor){ + LinkedList<REPCommand> output = new LinkedList<REPCommand>(); + LinkedList<REPCommand> cmds = new LinkedList<REPCommand>(); + //スタック上にあるコマンドを全部undoコマンドにする + while ( !unMergedCmds.isEmpty() ){ + REPCommand cmd0 = unMergedCmds.pop(); + output.add( createUndo(cmd0) ); + cmds.add(cmd0); + } + + /* 必要な分だけソートして返却用のリストに追加 */ + output.addAll( sortCmds(cmds) ); + + /* 残ったコマンドも再び実行させるが、まだマージされてないのでunMergedにも入れる */ + output.addAll(cmds); + for(REPCommand c: cmds) { + output.add(c); + unMergedCmds.push(c); + } + return editor.optimizedSend(output); + } + + public REPCommand prev() { + return sentCmds.poll(); + } + + private REPCommand createUndo(REPCommand cmd){ + REPCommand retCmd = new REPCommand(cmd); + 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; + } + + class REPCommandComparator implements Comparator<REPCommand>{ + + public int compare(REPCommand o1, REPCommand o2) { + + if ( o2.lineno > o1.lineno ) return 1; + else if ( o2.lineno < o1.lineno + || o2.eid > o1.eid ) + return -1; + + return 1; + } + + } + + private Collection<REPCommand> sortCmds(LinkedList<REPCommand> cmds) { + TreeSet<REPCommand> sortedCmds1 = new TreeSet<REPCommand>(new REPCommandComparator()); + int top; + int prevEid=-1; + while ( -1 != (top=getPrecedence(cmds, prevEid+1)) ){ + REPCommand tmp = cmds.remove(top); + sortedCmds1.add(tmp); + prevEid = tmp.eid; + } + + return sortedCmds1; + } + + /* search cmd. ordering by min EID that is lower lowEid and min SEQ. */ + private int getPrecedence(LinkedList<REPCommand> cmds, int lowEid) { + int cEid, cSeq; + cEid=cSeq=Integer.MAX_VALUE; + int ret=-1; + for (int i=0; i<cmds.size(); i++){ + REPCommand c = cmds.get(i); + if ( c.eid<lowEid ) continue; + else if ( c.eid>cEid ) continue; + else if ( c.eid==cEid ) { + if ( c.seq>cSeq ) continue; + cSeq=c.seq; + ret = i; + } else { /* tmp.eid<cEid */ + cEid = c.eid; + cSeq = c.seq; + ret = i; + } + } + return ret; + } + + /** + * Translate Command cmd that was received from SeMa. + * @param cmd the command to be translated. + * @return translated commannd. + */ + public void transReceiveCmd(Forwarder nextEditor,REPCommand cmd){ + assert (cmd.eid != eid); + // nop command の挿入は Editor 側で行って、こちら側ではやらない + unMergedCmds.push(cmd); + nextEditor.send(cmd); + } + + public void setEid(int _eid){ + eid = _eid; + } + + public Stack<REPCommand> getList() { + // TODO Auto-generated method stub + return unMergedCmds; + } + + public LinkedList<REPCommand> getSentCmds() { + // TODO Auto-generated method stub + return sentCmds; + } + + public void setUndoCommand(REPCommand command) { + // TODO Auto-generated method stub + undoReplaceList.add(command); + } + + public boolean checkMergeConflict(REPCommand command) { + // sentMergedList.remove(); + + if(mergeAgainList.size() > 0){ + mergeAgainList.add(command); + if(sentMergedList.size() == 0){ + return true; + } + } + + return false; + } + + public LinkedList<REPCommand> getMergeAgain() { + LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>(); + for(int i = 0; i < mergeAgainList.size(); i++){ + //eid = REP.MEGE_EID + returnCommand.add(createUndo(mergeAgainList.get(mergeAgainList.size() - i -1))); + } + for(REPCommand command : mergeAgainList){ + if(command.eid == REP.MERGE_EID.id){ + returnCommand.add(command); + } + } + for(REPCommand command : mergeAgainList){ + if(command.eid == eid){ + command.eid = REP.MERGE_EID.id; + returnCommand.add(command); + } + } + mergeAgainList.clear(); + sentMergedList = returnCommand; + return returnCommand; + } + + public boolean isFinished() { + if(unMergedCmds.size() > 0) return false; + if(sentMergedList.size() > 0) return false; + if(sentCmds.size() > 0) return false; + return true; + } + + public boolean isMerging() { + return merge_mode; + } + + public void startMerge(REPCommand cmd) { + merge_mode = true; + } + + public void mergeAck() { + + } + + public void endMerge() { + merge_mode = false; + } + + + +}