summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2007-09-07 04:27:47 (EDT)
committerEike Stepper2007-09-07 04:27:47 (EDT)
commitece6b9fb986c33f20f8069d748f5bbbe8ea0fe97 (patch)
treedeee5981662a9c9ad3629792cec5013fdff7f8d7
parented7c4a3c38c0e185bbf345e1d854a875f4a605a9 (diff)
downloadcdo-ece6b9fb986c33f20f8069d748f5bbbe8ea0fe97.zip
cdo-ece6b9fb986c33f20f8069d748f5bbbe8ea0fe97.tar.gz
cdo-ece6b9fb986c33f20f8069d748f5bbbe8ea0fe97.tar.bz2
[202064] More client-side intelligence (SmartReadAhead Thread)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=202064
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java92
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOInvalidationNotification.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOInvalidationNotificationImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java13
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java44
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java23
8 files changed, 166 insertions, 27 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
index c7b19df..8899d95 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
@@ -33,8 +33,8 @@ import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import java.text.MessageFormat;
-import java.util.Collection;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -187,7 +187,7 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
* TODO I can't see how recursion is controlled/limited
*/
public void collectContainedRevisions(CDORevisionImpl revision, int referenceChunk,
- Collection<CDORevisionImpl> containedRevisions)
+ Map<CDOID, CDORevisionImpl> containedRevisions)
{
RevisionManager revisionManager = getSessionManager().getRepository().getRevisionManager();
CDOClassImpl cdoClass = revision.getCDOClass();
@@ -203,9 +203,12 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
CDOID id = (CDOID)value;
if (!id.isNull())
{
- CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
- containedRevisions.add(containedRevision);
- collectContainedRevisions(containedRevision, referenceChunk, containedRevisions);
+ if (containedRevisions.get(id) == null)
+ {
+ CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
+ containedRevisions.put(id, containedRevision);
+ collectContainedRevisions(containedRevision, referenceChunk, containedRevisions);
+ }
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java
index 1a4c5ef..200aa63 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java
@@ -11,19 +11,27 @@
package org.eclipse.emf.cdo.internal.server.protocol;
import org.eclipse.emf.cdo.internal.protocol.CDOIDImpl;
+import org.eclipse.emf.cdo.internal.protocol.CDOIDNull;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
+import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl.MoveableList;
+import org.eclipse.emf.cdo.internal.server.RevisionManager;
import org.eclipse.emf.cdo.internal.server.Session;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.protocol.model.CDOClass;
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
/**
* @author Eike Stepper
@@ -36,6 +44,10 @@ public class LoadRevisionIndication extends CDOReadIndication
protected int referenceChunk;
+ protected Map<CDOClass, CDOFetchRule> fetchRules = new HashMap<CDOClass, CDOFetchRule>();
+
+ protected CDOID contextID = CDOIDNull.NULL;
+
public LoadRevisionIndication()
{
}
@@ -62,13 +74,27 @@ public class LoadRevisionIndication extends CDOReadIndication
if (PROTOCOL.isEnabled()) PROTOCOL.format("Read ID: {0}", id);
ids[i] = id;
}
+
+ int fetchSize = in.readInt();
+ if (fetchSize > 0)
+ {
+ contextID = CDOIDImpl.read(in);
+ for (int i = 0; i < fetchSize; i++)
+ {
+ CDOFetchRule fetchRule = new CDOFetchRule(in, getPackageManager());
+ for (CDOFeature feature : fetchRule.getFeatures())
+ {
+ fetchRules.put(fetchRule.getCDOClass(), fetchRule);
+ }
+ }
+ }
}
@Override
protected void responding(ExtendedDataOutputStream out) throws IOException
{
Session session = getSession();
- List<CDORevisionImpl> containedRevisions = new ArrayList<CDORevisionImpl>(0);
+ Map<CDOID, CDORevisionImpl> containedRevisions = new HashMap<CDOID, CDORevisionImpl>(0);
if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing {0} revisions", ids.length);
for (CDOID id : ids)
@@ -78,9 +104,17 @@ public class LoadRevisionIndication extends CDOReadIndication
session.collectContainedRevisions(revision, referenceChunk, containedRevisions);
}
+ if (!contextID.isNull() && fetchRules.size() > 0)
+ {
+ // TODO What is this good for? Why 1000?
+ int newReferenceChunk = Math.max(referenceChunk, 1000);
+ CDORevisionImpl revisionContext = getRevision(contextID);
+ collectRevisionsByRule(revisionContext, newReferenceChunk, containedRevisions, new HashSet<CDOFetchRule>());
+ }
+
out.writeInt(containedRevisions.size());
if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing {0} additional revisions", containedRevisions.size());
- for (CDORevisionImpl revision : containedRevisions)
+ for (CDORevisionImpl revision : containedRevisions.values())
{
revision.write(out, session, referenceChunk);
}
@@ -90,4 +124,54 @@ public class LoadRevisionIndication extends CDOReadIndication
{
return getRevisionManager().getRevision(id, referenceChunk);
}
+
+ private void collectRevisionsByRule(CDORevisionImpl revision, int referenceChunk,
+ Map<CDOID, CDORevisionImpl> containedRevisions, Set<CDOFetchRule> workingFetchRules)
+ {
+ CDOFetchRule fetchRule = fetchRules.get(revision.getCDOClass());
+ if (fetchRule == null || workingFetchRules.contains(fetchRule))
+ {
+ return;
+ }
+
+ workingFetchRules.add(fetchRule);
+ RevisionManager revisionManager = getSessionManager().getRepository().getRevisionManager();
+ for (CDOFeature feature : fetchRule.getFeatures())
+ {
+ if (feature.isMany())
+ {
+ MoveableList list = revision.getList(feature);
+ int toIndex = Math.min(referenceChunk, list.size()) - 1;
+ for (int i = 0; i <= toIndex; i++)
+ {
+ Object value = list.get(i);
+ if (value instanceof CDOID)
+ {
+ CDOID id = (CDOID)value;
+ // TODO Missing here? if (!id.isNull() &&
+ // !containedRevisions.containsKey(id))
+ CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
+ containedRevisions.put(containedRevision.getID(), containedRevision);
+ collectRevisionsByRule(containedRevision, referenceChunk, containedRevisions, workingFetchRules);
+ }
+ }
+ }
+ else
+ {
+ Object value = revision.getValue(feature);
+ if (value instanceof CDOID)
+ {
+ CDOID id = (CDOID)value;
+ if (!id.isNull() && !containedRevisions.containsKey(id))
+ {
+ CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
+ containedRevisions.put(containedRevision.getID(), containedRevision);
+ collectRevisionsByRule(containedRevision, referenceChunk, containedRevisions, workingFetchRules);
+ }
+ }
+ }
+ }
+
+ workingFetchRules.remove(fetchRule);
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOInvalidationNotification.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOInvalidationNotification.java
index e2ff82f..487c2df 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOInvalidationNotification.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOInvalidationNotification.java
@@ -14,7 +14,7 @@ package org.eclipse.emf.cdo;
import org.eclipse.emf.common.notify.Notification;
/**
- * @author Simon McDuff
+ * @author Eike Stepper
*/
public interface CDOInvalidationNotification extends Notification
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOInvalidationNotificationImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOInvalidationNotificationImpl.java
index e13e84c..83c34dd 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOInvalidationNotificationImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOInvalidationNotificationImpl.java
@@ -16,7 +16,7 @@ import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
/**
- * @author Simon McDuff
+ * @author Eike Stepper
*/
public class CDOInvalidationNotificationImpl implements CDOInvalidationNotification
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java
index f04432a..c1d2308 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionResolverImpl;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl.MoveableList;
import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.cdo.protocol.analyzer.IFetchRuleManager;
import org.eclipse.emf.cdo.protocol.model.CDOFeature;
import org.eclipse.emf.cdo.protocol.revision.CDOReferenceProxy;
import org.eclipse.emf.cdo.protocol.util.TransportException;
@@ -38,6 +39,8 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C
{
private CDOSessionImpl session;
+ private IFetchRuleManager ruleManager = IFetchRuleManager.NOOP;
+
public CDORevisionManagerImpl(CDOSessionImpl session)
{
this.session = session;
@@ -247,4 +250,14 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C
throw new TransportException(ex);
}
}
+
+ public IFetchRuleManager getRuleManager()
+ {
+ return ruleManager;
+ }
+
+ public void setRuleManager(IFetchRuleManager ruleManager)
+ {
+ this.ruleManager = ruleManager;
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
index 382987c..097b66e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
@@ -106,6 +106,7 @@ public final class CDOStore implements EStore
TRACER.format("get({0}, {1}, {2})", cdoObject, cdoFeature, index);
}
+ view.getFeatureAnalyzer().preTraverseFeature(cdoObject.cdoRevision(), cdoFeature, index);
CDORevisionImpl revision = getRevisionForReading(cdoObject);
Object value = get(revision, cdoFeature, index);
if (cdoFeature.isReference())
@@ -119,6 +120,7 @@ public final class CDOStore implements EStore
value = view.convertIDToObject(value);
}
+ view.getFeatureAnalyzer().postTraverseFeature(cdoObject.cdoRevision(), cdoFeature, index);
return value;
}
@@ -132,7 +134,7 @@ public final class CDOStore implements EStore
{
MoveableList list = revision.getList(cdoFeature);
int fromIndex = index;
- int toIndex = Math.min(index + chunkSize - 1, list.size());
+ int toIndex = Math.min(index + chunkSize, list.size()) - 1;
Set<CDOID> notRegistered = new HashSet<CDOID>();
for (int i = fromIndex; i <= toIndex; i++)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
index 0695148..9a6ad953 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
@@ -7,7 +7,9 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
- * Simon McDuff - EMF invalidation notifications
+ * Simon McDuff - EMF invalidation notifications,
+ * IFeatureAnalyzer,
+ * LoadRevisionCollectionChunk
**************************************************************************/
package org.eclipse.emf.internal.cdo;
@@ -23,6 +25,7 @@ import org.eclipse.emf.cdo.internal.protocol.revision.CDOIDProvider;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.CDOIDTyped;
+import org.eclipse.emf.cdo.protocol.analyzer.IFeatureAnalyzer;
import org.eclipse.emf.cdo.protocol.model.CDOClass;
import org.eclipse.emf.cdo.protocol.model.CDOClassRef;
import org.eclipse.emf.cdo.protocol.revision.CDORevisionResolver;
@@ -73,6 +76,10 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
private boolean enableInvalidationNotifications;
+ private int loadRevisionCollectionChunkSize = 1;
+
+ private IFeatureAnalyzer featureAnalyzer = IFeatureAnalyzer.NOOP;
+
private Map<CDOID, InternalCDOObject> objects = new HashMap<CDOID, InternalCDOObject>();
private CDOStore store = new CDOStore(this);
@@ -81,13 +88,10 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
private InternalCDOObject lastLookupObject;
- private int loadRevisionCollectionChunkSize;
-
public CDOViewImpl(int id, CDOSessionImpl session)
{
this.viewID = id;
this.session = session;
- this.loadRevisionCollectionChunkSize = 1;
}
public int getViewID()
@@ -127,7 +131,27 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
public void setEnableInvalidationNotifications(boolean on)
{
- this.enableInvalidationNotifications = on;
+ enableInvalidationNotifications = on;
+ }
+
+ public int getLoadRevisionCollectionChunkSize()
+ {
+ return loadRevisionCollectionChunkSize;
+ }
+
+ public void setLoadRevisionCollectionChunkSize(int loadRevisionCollectionChunkSize)
+ {
+ this.loadRevisionCollectionChunkSize = loadRevisionCollectionChunkSize;
+ }
+
+ public IFeatureAnalyzer getFeatureAnalyzer()
+ {
+ return featureAnalyzer;
+ }
+
+ public void setFeatureAnalyzer(IFeatureAnalyzer featureAnalyzer)
+ {
+ this.featureAnalyzer = featureAnalyzer == null ? IFeatureAnalyzer.NOOP : featureAnalyzer;
}
public CDOTransactionImpl toTransaction()
@@ -782,14 +806,4 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
return MessageFormat.format("CDOViewResourcesEvent[{0}, {1}, {2}]", getView(), resourcePath, kind);
}
}
-
- public int getLoadRevisionCollectionChunkSize()
- {
- return loadRevisionCollectionChunkSize;
- }
-
- public void setLoadRevisionCollectionChunkSize(int loadRevisionCollectionChunkSize)
- {
- this.loadRevisionCollectionChunkSize = loadRevisionCollectionChunkSize;
- }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java
index 2bb1195..f32846b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java
@@ -11,9 +11,11 @@
package org.eclipse.emf.internal.cdo.protocol;
import org.eclipse.emf.cdo.internal.protocol.CDOIDImpl;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.protocol.analyzer.IFetchRuleManager;
import org.eclipse.net4j.IChannel;
import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
@@ -74,6 +76,27 @@ public class LoadRevisionRequest extends CDOClientRequest<List<CDORevisionImpl>>
if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing ID: {0}", id);
CDOIDImpl.write(out, id);
}
+
+ IFetchRuleManager ruleManager = getSession().getRevisionManager().getRuleManager();
+ List<CDOFetchRule> fetchRules = ruleManager.getFetchRules(ids);
+ if (fetchRules == null || fetchRules.size() == 0)
+ {
+ out.writeInt(0);
+ }
+ else
+ {
+ int fetchSize = fetchRules.size();
+ out.writeInt(fetchSize);
+ if (fetchSize > 0)
+ {
+ CDOID contextID = ruleManager.getContext();
+ CDOIDImpl.write(out, contextID);
+ for (CDOFetchRule fetchRule : fetchRules)
+ {
+ fetchRule.write(out);
+ }
+ }
+ }
}
@Override