annotate rep/handler/Translator.java @ 431:1bb59652d89c

fixing merge...
author one
date Sun, 03 Jan 2010 01:01:52 +0900
parents 622a8e15ff40
children bd883b059360
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
1 package rep.handler;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
2
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
3 import java.util.Comparator;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
4 import java.util.LinkedList;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
5 import java.util.List;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
6 import java.util.TreeSet;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
7
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
8 import rep.REP;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
9 import rep.REPCommand;
407
de4ef4313adc looks like working...
one
parents: 397
diff changeset
10 import rep.SessionManager;
421
f8916a96a373 (no commit message)
one
parents: 411
diff changeset
11 import rep.channel.REPLogger;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
12 import rep.optimizers.REPCommandOptimizer;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
13
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
14 public class Translator {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
15 public int eid;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
16
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
17 public REPCommandOptimizer optimizer;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
18 private LinkedList<REPCommand> unMergedCmds;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
19 public LinkedList<REPCommand> sentMergedList;
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
20 boolean mergeAgain;
421
f8916a96a373 (no commit message)
one
parents: 411
diff changeset
21 public REPLogger logger = SessionManager.logger;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
22 boolean merge_mode = false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
23
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
24 public Translator(int _eid,REPCommandOptimizer opt){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
25 eid = _eid;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
26 optimizer = opt;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
27 unMergedCmds = new LinkedList<REPCommand>();
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
28 mergeAgain = false;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
29 sentMergedList = new LinkedList<REPCommand>();
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
30 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
31
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
32 /**
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
33 * New command from an editor
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
34 * The command is sent to the next editor
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
35 * @param cmd
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
36 * @return translated command.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
37 */
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
38 public REPCommand transSendCmd(REPCommand cmd){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
39 assert(cmd.eid==eid);
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
40 unMergedCmds.addLast(cmd);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
41
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
42 //マージ中にユーザから割り込みがあった場合
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
43 if(isMerging()){
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
44 mergeAgain = true;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
45 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
46
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
47 return cmd;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
48 }
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
49
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
50 /**
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
51 * My command is returned from the session ring, and START_MERGE_ACK
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
52 * is returned. At this
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
53 * stage my writeQueue is empty, our editor is waiting for me.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
54 * Start merge process.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
55 * @param cmd
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
56 */
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
57 public boolean catchOwnCommand(REPNode editor, int eid){
427
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
58 logger.writeLog("beforeMerge:"+unMergedCmds);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
59 LinkedList<REPCommand> output = new LinkedList<REPCommand>();
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
60 TreeSet<REPCommand> cmds = new TreeSet<REPCommand>(new REPCommandComparator(eid));
427
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
61 // merge queue上にあるコマンドを全部undoコマンドするのと同時に
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
62 // sort したコマンド列を生成する
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
63 for( REPCommand cmd0 : unMergedCmds) {
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
64 output.add( createUndo(cmd0) );
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
65 }
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
66 for( REPCommand cmd0 : editor.getSentList()) {
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
67 cmds.add(cmd0);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
68 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
69 output.addAll(cmds);
427
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
70 // ACKが来たものは必ず先頭
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
71
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
72 // unMerged command のdeleteのundo string は、この時点で使えない。
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
73 // Editor 側から送り返して来たものを使う必要がある。
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
74 unMergedCmds.clear();
426
1acc3dfde5d3 minor fix.
one
parents: 421
diff changeset
75 logger.writeLog("outputMerge:"+output);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
76 return optimizedSend(editor,output);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
77 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
78
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
79 /**
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
80 * Sent optimized merged command list
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
81 * @param editor
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
82 * @param output
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
83 * @return if any sent commands output
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
84 */
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
85 public boolean optimizedSend(REPNode editor, LinkedList<REPCommand> output) {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
86 List<REPCommand> output1 = optimizer.optimize(output);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
87 if (output1.size()==0) {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
88 merge_mode = false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
89 return false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
90 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
91 for(REPCommand c:output1) {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
92 REPCommand m = new REPCommand(c);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
93 m.setEID(REP.MERGE_EID.id);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
94 m.setSEQID(editor.seq());
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
95 sentMergedList.add(m);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
96 editor.send(m);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
97 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
98 merge_mode = true;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
99 return true;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
100 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
101
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
102 private REPCommand createUndo(REPCommand cmd){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
103 REPCommand retCmd = new REPCommand(cmd);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
104 if (cmd.cmd==REP.REPCMD_INSERT) retCmd.cmd=REP.REPCMD_DELETE;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
105 else if (cmd.cmd==REP.REPCMD_DELETE) retCmd.cmd=REP.REPCMD_INSERT;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
106 return retCmd;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
107 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
108
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
109 class REPCommandComparator implements Comparator<REPCommand>{
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
110 int base;
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
111 REPCommandComparator(int base) {
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
112 this.base = base;
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
113 }
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
114 public int compare(REPCommand o1, REPCommand o2) {
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
115 int eid1 = o1.eid-base; if (eid1<0) eid1 += Integer.MAX_VALUE;
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
116 int eid2 = o2.eid-base; if (eid2<0) eid2 += Integer.MAX_VALUE;
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
117 if ( eid1<eid2 ) return -1;
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
118 if ( eid1>eid2 ) return 1;
427
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
119 if ( o1.seq<o2.seq ) return -1;
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
120 if ( o1.seq>o2.seq ) return 1;
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
121 assert(false);
622a8e15ff40 Merge Worked ?
one
parents: 426
diff changeset
122 return 0;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
123 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
124 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
125
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
126 /**
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
127 * Translate Command cmd that was received from SeMa.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
128 * @param cmd the command to be translated.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
129 * @return translated commannd.
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
130 */
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
131 public void transReceiveCmd(REPNode nextEditor,REPCommand cmd){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
132 assert (cmd.eid != eid);
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
133 unMergedCmds.addLast(cmd);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
134 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
135
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
136 public void setEid(int _eid){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
137 eid = _eid;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
138 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
139
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
140 public boolean checkMergeConflict(REPCommand command) {
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
141 unMergedCmds.addLast(command);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
142 REPCommand prev = sentMergedList.remove();
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
143 //assert (prev.seq==command.seq);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
144
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
145 if (mergeAgain) {
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
146 return true;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
147 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
148 if(sentMergedList.size()==0) {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
149 merge_mode=false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
150 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
151 return false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
152 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
153
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
154 public void getMergeAgain(REPNode editor) {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
155 LinkedList<REPCommand> returnCommand = new LinkedList<REPCommand>();
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
156 LinkedList<REPCommand> merge = new LinkedList<REPCommand>();
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
157 LinkedList<REPCommand> conflict = new LinkedList<REPCommand>();
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
158 for(REPCommand command : unMergedCmds) {
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
159 returnCommand.add(createUndo(command));
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
160 }
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
161 for(REPCommand command : unMergedCmds) {
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
162 if(command.eid == REP.MERGE_EID.id){
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
163 merge.addLast(command);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
164 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
165 }
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
166 for(REPCommand command : unMergedCmds){
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
167 if(command.eid == eid){
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
168 command.eid = REP.MERGE_EID.id;
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
169 conflict.addLast(command);
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
170 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
171 }
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
172 unMergedCmds.clear();
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
173 returnCommand.addAll(merge);
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
174 returnCommand.addAll(conflict);
411
795ef563f2a0 add commnets
one
parents: 407
diff changeset
175 // int count = 0;
795ef563f2a0 add commnets
one
parents: 407
diff changeset
176 // for(REPCommand command: returnCommand) {
795ef563f2a0 add commnets
one
parents: 407
diff changeset
177 // switch(command.cmd) {
795ef563f2a0 add commnets
one
parents: 407
diff changeset
178 // case REPCMD_INSERT: count++; break;
795ef563f2a0 add commnets
one
parents: 407
diff changeset
179 // case REPCMD_DELETE: count--; break;
795ef563f2a0 add commnets
one
parents: 407
diff changeset
180 // default: assert false;
795ef563f2a0 add commnets
one
parents: 407
diff changeset
181 // }
795ef563f2a0 add commnets
one
parents: 407
diff changeset
182 // }
421
f8916a96a373 (no commit message)
one
parents: 411
diff changeset
183 logger.writeLog("MergeAgain ret="+returnCommand.size());
411
795ef563f2a0 add commnets
one
parents: 407
diff changeset
184 // +" increment="+count);
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
185 mergeAgain = false;
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
186 optimizedSend(editor, returnCommand);
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
187 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
188
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
189 public boolean isFinished() {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
190 if(unMergedCmds.size() > 0) return false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
191 if(sentMergedList.size() > 0) return false;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
192 return true;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
193 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
194
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
195 public boolean isMerging() {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
196 return merge_mode;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
197 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
198
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
199 public void startMerge(REPCommand cmd) {
431
1bb59652d89c fixing merge...
one
parents: 427
diff changeset
200 logger.writeLog("START MERGE command ="+cmd+" and top of unMergedCmds = "+ unMergedCmds.getLast());
390
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
201 merge_mode = true;
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
202 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
203
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
204 public void mergeAck() {
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
205 }
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
206
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
207
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
208
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
diff changeset
209 }