From 4a96223d3206841b79b89be67e517c655ebb2417 Mon Sep 17 00:00:00 2001 From: slewis Date: Tue, 30 Dec 2008 16:51:52 +0000 Subject: Fixes for cola bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=234142 --- .../sync/doc/cola/ColaDocumentChangeMessage.java | 13 +++++- .../sync/doc/cola/ColaSynchronizationStrategy.java | 50 ++++++++++++++-------- .../ecf/sync/doc/DocumentChangeMessage.java | 4 +- 3 files changed, 44 insertions(+), 23 deletions(-) (limited to 'framework/bundles/org.eclipse.ecf.sync') diff --git a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaDocumentChangeMessage.java b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaDocumentChangeMessage.java index 358bff8d3..dea9abba1 100644 --- a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaDocumentChangeMessage.java +++ b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaDocumentChangeMessage.java @@ -91,8 +91,17 @@ public class ColaDocumentChangeMessage extends DocumentChangeMessage { public String toString() { final StringBuffer buf = new StringBuffer("ColaDocumentChangeMessage["); //$NON-NLS-1$ - buf.append("text=").append(getText()).append(";offset=").append(getOffset()); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(";length=").append(getLengthOfReplacedText()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ + String tType = "undefined"; + if (transformType == 0) { + tType = "insert"; + } else if (transformType == 1) { + tType = "delete"; + } else if (transformType == 2) { + tType = "replace"; + } + buf.append("transformType="+tType); + buf.append(";offset=").append(getOffset()); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(";length=").append(getLengthOfReplacedText()).append(";text=").append(getText()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ buf.append(";operationsCount[local=").append(getLocalOperationsCount()); //$NON-NLS-1$ buf.append(";remote=").append(getRemoteOperationsCount()).append("]]"); //$NON-NLS-1$//$NON-NLS-2$ return buf.toString(); diff --git a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaSynchronizationStrategy.java b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaSynchronizationStrategy.java index 901d61c3c..cd5f2361c 100644 --- a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaSynchronizationStrategy.java +++ b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/internal/sync/doc/cola/ColaSynchronizationStrategy.java @@ -11,6 +11,7 @@ package org.eclipse.ecf.internal.sync.doc.cola; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; @@ -35,7 +36,7 @@ import org.eclipse.osgi.util.NLS; public class ColaSynchronizationStrategy implements IModelSynchronizationStrategy { // - private final LinkedList unacknowledgedLocalOperations; + private final List unacknowledgedLocalOperations; private final boolean isInitiator; private long localOperationsCount; private long remoteOperationsCount; @@ -51,10 +52,16 @@ public class ColaSynchronizationStrategy implements IModelSynchronizationStrateg } public static ColaSynchronizationStrategy getInstanceFor(ID client, boolean isInitiator) { - if (sessionStrategies.get(client) == null) { - sessionStrategies.put(client, new ColaSynchronizationStrategy(isInitiator)); + ColaSynchronizationStrategy existingStrategy = (ColaSynchronizationStrategy) sessionStrategies.get(client); + if (existingStrategy != null) { + Boolean existingStrategyIsInitiator = new Boolean(existingStrategy.isInitiator); + if (existingStrategyIsInitiator.equals(new Boolean(isInitiator))) { + return existingStrategy; + } } - return (ColaSynchronizationStrategy) sessionStrategies.get(client); + existingStrategy = new ColaSynchronizationStrategy(isInitiator); + sessionStrategies.put(client, existingStrategy); + return existingStrategy; } public static void cleanUpFor(ID client) { @@ -64,18 +71,6 @@ public class ColaSynchronizationStrategy implements IModelSynchronizationStrateg public static void dispose() { sessionStrategies.clear(); } - - public DocumentChangeMessage registerOutgoingMessage(DocumentChangeMessage localMsg) { - Trace.entering(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_ENTERING, this.getClass(), "registerOutgoingMessage", localMsg); //$NON-NLS-1$ - final ColaDocumentChangeMessage colaMsg = new ColaDocumentChangeMessage(localMsg, localOperationsCount, remoteOperationsCount); - if (!colaMsg.isReplacement()) { - unacknowledgedLocalOperations.add(colaMsg); - localOperationsCount++; - } - Trace.exiting(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_EXITING, this.getClass(), "registerOutgoingMessage", colaMsg); //$NON-NLS-1$ - return colaMsg; - } - /** * Handles proper transformation of incoming ColaDocumentChangeMessages. * Returned DocumentChangeMessages can be applied directly to the @@ -95,6 +90,7 @@ public class ColaSynchronizationStrategy implements IModelSynchronizationStrateg transformedRemotes.add(transformedRemote); remoteOperationsCount++; + Trace.trace(Activator.PLUGIN_ID, "unacknowledgedLocalOperations="+unacknowledgedLocalOperations); //this is where the concurrency algorithm is executed if (!unacknowledgedLocalOperations.isEmpty()) {//Do not remove this. It is necessary. The following iterator does not suffice. // remove operations from queue that have been implicitly @@ -123,7 +119,7 @@ public class ColaSynchronizationStrategy implements IModelSynchronizationStrateg // don't require to be transformed against if (!unacknowledgedLocalOperations.isEmpty()) { - ColaDocumentChangeMessage localOp = (ColaDocumentChangeMessage) unacknowledgedLocalOperations.getFirst(); + ColaDocumentChangeMessage localOp = (ColaDocumentChangeMessage) unacknowledgedLocalOperations.get(0); Assert.isTrue(transformedRemote.getRemoteOperationsCount() == localOp.getLocalOperationsCount()); for (final ListIterator unackOpsListIt = unacknowledgedLocalOperations.listIterator(); unackOpsListIt.hasNext();) { @@ -196,17 +192,33 @@ public class ColaSynchronizationStrategy implements IModelSynchronizationStrateg * @see org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategy#registerLocalChange(org.eclipse.ecf.sync.doc.IModelChange) */ public IModelChangeMessage[] registerLocalChange(IModelChange localChange) { + List results = new ArrayList(); Trace.entering(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_ENTERING, this.getClass(), "registerLocalChange", localChange); //$NON-NLS-1$ if (localChange instanceof IDocumentChange) { final IDocumentChange docChange = (IDocumentChange) localChange; final ColaDocumentChangeMessage colaMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(), docChange.getLengthOfReplacedText(), docChange.getText()), localOperationsCount, remoteOperationsCount); + // If not replacement, we simply add to unacknowledgedLocalOperations and add message + // to results if (!colaMsg.isReplacement()) { unacknowledgedLocalOperations.add(colaMsg); localOperationsCount++; + results.add(colaMsg); + } else { + // It *is a replacement message, so we add both a delete and an insert message + // First create/add a delete message (text set to "")... + ColaDocumentChangeMessage delMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(),docChange.getLengthOfReplacedText(),""), localOperationsCount, remoteOperationsCount); + unacknowledgedLocalOperations.add(delMsg); + localOperationsCount++; + results.add(delMsg); + // Then create/add the insert message (length set to 0) + ColaDocumentChangeMessage insMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(),0,docChange.getText()), localOperationsCount, remoteOperationsCount); + unacknowledgedLocalOperations.add(insMsg); + localOperationsCount++; + results.add(insMsg); } Trace.exiting(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_EXITING, this.getClass(), "registerLocalChange", colaMsg); //$NON-NLS-1$ - return new IModelChangeMessage[] {colaMsg}; - } else return new IModelChangeMessage[0]; + } + return (IModelChangeMessage[]) results.toArray(new IModelChangeMessage[] {}); } /* (non-Javadoc) diff --git a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/sync/doc/DocumentChangeMessage.java b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/sync/doc/DocumentChangeMessage.java index a90643453..02a46e2d3 100644 --- a/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/sync/doc/DocumentChangeMessage.java +++ b/framework/bundles/org.eclipse.ecf.sync/src/org/eclipse/ecf/sync/doc/DocumentChangeMessage.java @@ -108,8 +108,8 @@ public class DocumentChangeMessage implements IDocumentChange, IModelChangeMessa public String toString() { final StringBuffer buf = new StringBuffer("DocumentChangeMessage["); //$NON-NLS-1$ - buf.append("text=").append(text).append(";offset=").append(offset); //$NON-NLS-1$ //$NON-NLS-2$ - buf.append(";length=").append(length).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append("offset=").append(offset); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(";length=").append(length).append(";text=").append(text).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ return buf.toString(); } -- cgit v1.2.3