changeset 486:877aacde8651

new merge on going...
author one
date Thu, 21 Oct 2010 20:30:52 +0900
parents cc262a519b8a
children 455df381449a
files Todo rep/handler/Editor.java
diffstat 2 files changed, 103 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Wed Oct 20 22:59:19 2010 +0900
+++ b/Todo	Thu Oct 21 20:30:52 2010 +0900
@@ -1,18 +1,66 @@
+Thu Oct 21 12:27:44 JST 2010
+
+外部からのINESRT に USER_INSERTがはまりこんでいるが…
+
+    Editor               SM
+                                          <---INSERT----
+       <---INSERT----       (start_merge)
+       --U_INSERT1-->       truncate
+       ----INSERT--->       start_merge
+       --U_INSERT2-->       truncate
+       <--START_M----       (U_INSERT1, U_INSERT2)
+
+INSERTが来た時点でEditorをlockすれば、二つめは止めるが。
+でも、問題はないはず。余計に tuncate しても問題ない。
+
+                                          --U_INSERT0-->
+                            (U_INSERT0)
+                                          <---INSERT----
+       <---INSERT----       (start_merge)
+       --U_INSERT1-->                     --U_INSERT1-->
+       ----INSERT--->       start_merge
+                            (U_INSERT0, U_INSERT1, INSERT)
+                                          --INSERT-->
+       --U_INSERT2-->                     --U_INSERT2-->
+       <--START_M----       (U_INSERT0, U_INSERT1, INSERT, *,  U_INSERT2)
+       --U_INSERT3-->                     --U_INSERT3-->
+       --STARTM_ACK->
+       --U_INSERT4-->       (U_INSERT0, U_INSERT1, INSERT, *,  U_INSERT2, U_INSERT3, U_INSERT4)
+                                          --U_INSERT4-->
+
+ええと、INSERT は、U_INSERT[01] は追い越すべき。U_INSERT[2-4]
+は追い越さない。* は merge_mark
+
+start_merge 以降は外部commandはブロックされるので問題ない。
+
+ってことは、まずいっていうことね。U_INSERT1/U_INSERT2 を
+block しても良いのだが、undo は必要なのでblock出来ません。
+
+    sentList, unMegeList には随時追加 (merge 中はtruncateしない)
+    sort は、MERGE_MARK まで
+    merge_end で、user command があれば、truncate
+
+かな。で、preMergedCommand の送信タイミングは? 戻って来た順に出してしまって良い?
+
 Wed Oct 20 20:35:53 JST 2010
 
-    Editor1   Editor2    Editor3 
-    c(eid=1)             a(eid=3)
-    a(eid=3)  c(eid=1)           
-              e(eid=2)   c(eid=1)
-    c(eid=1)  a(eid=3)   e(eid=2)
-    e(eid=2)  ca(eid=1)  a(eid=3)
-    aa(eid=3) e(eid=2)   ca(eid=1)
-    ca(eid=1) aa(eid=3)  ea(eid=2)   
-    ea(eid=2) ca(eid=1)
-                        ca(eid=1)
+    Editor1    Editor2    Editor3 
+    c(eid=1)              a(eid=3)
+    a(eid=3)*  c(eid=1)*          
+               e(eid=2)t  c(eid=1)*
+    c(eid=1)t  a(eid=3)*  e(eid=2)*
+    e(eid=2)*  ca(eid=1)t a(eid=3)t
+    aa(eid=3)t e(eid=2)t  ca(eid=1)t
+    ca(eid=1)t aa(eid=3)t ea(eid=2)t  
+    ea(eid=2)t ca(eid=1)t
+                          ca(eid=1)t
 
     [c,e,a]   [c,e,a]    [c,e,a]
 
+sort は、どの範囲?
+    全部で良い
+と言うことは、そこに MERGE_MARK は必要ない
+
 
 Fri Oct 15 19:47:05 JST 2010
 
--- a/rep/handler/Editor.java	Wed Oct 20 22:59:19 2010 +0900
+++ b/rep/handler/Editor.java	Thu Oct 21 20:30:52 2010 +0900
@@ -31,7 +31,9 @@
 	private TreeSet<REPCommand> sortedEditCmds;
 	boolean mergeAgain;
 	public REPLogger logger = SessionManager.logger;
-	boolean merge_mode = false;
+	boolean merging = false;
+	private LinkedList<REPCommand> writeQueue = new LinkedList<REPCommand>();
+	private REPCommand mergeMark =new REPCommand(REP.REPCMD_MERGE_MARK,0,0, REP.MERGE_EID.id, 0, "");
 	
 	public enum MergeMode {
 		NoMerge,    // no merge 
@@ -39,10 +41,8 @@
 		Early,         //  merge at returned command and Ack
 		Direct        //  merge at incoming command
 	}
-	private boolean merging;
+	public static  MergeMode mergeMode = MergeMode.Direct;
 	static final boolean doOptimize = false;
-	private LinkedList<REPCommand> writeQueue = new LinkedList<REPCommand>(); 
-	public static  MergeMode mergeMode = MergeMode.Direct;
 
 	public Editor(SessionManager manager,int editorNo){
 		// no translator case
@@ -138,7 +138,7 @@
 			if (mergeMode==MergeMode.Direct) {
 				checkAck(command);
 				truncateUnMergedCmds(command);
-				ServerMainLoop.logger.writeLog("Editor"+eid+": send ackCommand "+command);
+				ServerMainLoop.logger.writeLog("Editor"+eid+": send ackCommand "+command+report());
 				next.send(command);
 				checkQuit();
 			} else
@@ -181,9 +181,11 @@
 
 			//他のエディタからの編集コマンド
 			transReceiveCmd(next,command);
-			if (mergeMode==MergeMode.Direct) 
+			if (mergeMode==MergeMode.Direct)  { 
+				sendEditorCommand(command);
+				sentList.addLast(mergeMark );
 				startMerge(command);
-			else
+			} else
 				sendEditorCommand(command);
 			return;
 		default:
@@ -193,8 +195,10 @@
 
 	private void userEditorCommand(REPCommand command) {
 		//エディタからの新たな編集コマンド
-		if (mergeMode==MergeMode.Direct)
+		if (mergeMode==MergeMode.Direct) {
 			truncateSentList(command);
+			ServerMainLoop.logger.writeLog("Editor"+eid+": User Command "+command+report());
+		}
 		if (next==this) return; // singleton case
 		transSendCmd(command);
 		sendEditorCommand(command);
@@ -383,7 +387,9 @@
 		REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,"");
 		sendToEditor(mergeEnd);
 		if (mergeMode==MergeMode.Direct) {
-			sendEditorCommand(preMergeCommand);
+			REPCommand last = sentList.getLast();
+			if (last!=null && last.eid==eid && last.sid==sid)
+				truncateSentList(last);
 			preMergeCommand = null;
 			return ;
 		}
@@ -407,8 +413,13 @@
 	 * truncate sentList and unMergedCmds.
 	 */
 	private void truncateSentList(REPCommand commit) {
+		if (merging) {
+			preMergeCommand = commit;
+			return;
+		}
 		LinkedList<REPCommand>u = new LinkedList<REPCommand>();
 		for(REPCommand command:unMergedCmds) {
+			if (command.cmd==REP.REPCMD_MERGE_MARK) continue;
 			if (command.eid!=eid) 	break;
 			u.addLast(command);
 		}		
@@ -430,8 +441,10 @@
 	 * @param commit
 	 */
 	public void truncateUnMergedCmds(REPCommand commit) {
+		// assert(!merging);  merging でもすり抜ける場合がある
 		LinkedList<REPCommand>u = new LinkedList<REPCommand>();
 		for(REPCommand command:unMergedCmds) {
+			if (command.cmd==REP.REPCMD_MERGE_MARK) continue;
 			if (command.isSameSeq(commit)) 	break;
 			u.addLast(command);
 		}		
@@ -635,18 +648,31 @@
 
 		sortedEditCmds = new TreeSet<REPCommand>(new REPCommandComparator(1));
 		logger.writeLog("sentList"+eid+":"+sentList);
+		boolean flag = true;
 		for( REPCommand cmd0 : sentList ) {
+			if (mergeMode==MergeMode.Direct) {
+				if (cmd0.cmd==REP.REPCMD_MERGE_MARK) { 
+					flag = false;
+				}
+			}
 			if (cmd0.cmd==REP.REPCMD_INSERT || cmd0.cmd==REP.REPCMD_DELETE) {
-					sortedEditCmds.add(cmd0);
+				if (flag)	sortedEditCmds.add(cmd0);
+				else newSentList.add(cmd0);
 			}
 		}
 		output.addAll(sortedEditCmds);
-		output.addLast(new REPCommand(REP.REPCMD_MERGE_MARK,0,sid, REP.MERGE_EID.id, seq(), ""));
+		if (mergeMode==MergeMode.Direct) {
+			output.addAll(newSentList);
+			output.remove(mergeMark);
+			sentList.remove(mergeMark);
+		} else
+			output.addLast(mergeMark);
 		logger.writeLog("sortedMerge"+eid+":"+sortedEditCmds);
 		// unMerged command のdeleteのundo string は、この時点で使えない。
 		// Editor 側から送り返して来たものを使う必要がある。
 		unMergedCmds.clear();
-		sentList = newSentList;
+		if (mergeMode!=MergeMode.Direct)
+			sentList = newSentList;
 		logger.writeLog("outputMerge"+eid+":"+output);
 		return optimizedSend(this,output);
 	}
@@ -664,7 +690,7 @@
 		sentMergedList.clear();
 		List<REPCommand> output1 = optimizer.optimize(output);
 		if (output1.size()==0) {
-			merge_mode = false;
+			merging = false;
 			return false;
 		}
 		for(REPCommand c:output1) {
@@ -675,7 +701,7 @@
 			editor.sendToEditor(m);
 		}
 		logger.writeLog("OptimizedOutputMerge"+eid+":"+sentMergedList);
-		merge_mode = true;
+		merging = true;
 		return true;
 	}
 	
@@ -731,7 +757,7 @@
 		//  previous merge command may be returned
 
 		if(sentMergedList.size()==0 && !mergeAgain) {
-			merge_mode=false;
+			merging=false;
 		}
 		return mergeAgain;
 	}
@@ -760,7 +786,7 @@
 //	}
 
 	public boolean isMerging() {
-		return merge_mode;
+		return merging;
 	}
 
 	/**
@@ -769,7 +795,7 @@
 	public void mergeAck() {
 		logger.writeLog("Editor"+eid+": START MERGE "+
 				((unMergedCmds.size()>0)?" and top of unMergedCmds = "+ unMergedCmds.getLast():""));
-		merge_mode = true;
+		merging = true;
 	}
 
 	/**
@@ -777,10 +803,10 @@
 	 */
 	public String report() {
 		String s = "";
-		s += "SentList:"+sentList;
+		s += "\n  sentList:"+sentList;
 		s += "\n  ackList:"+ackList;
 		s += "\n  unMergedList:"+unMergedCmds;
-		s += "\n  mergeMode=:"+merge_mode;
+		s += "\n  mergeMode=:"+merging;
 		return s;
 	}