summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2007-09-10 03:38:31 (EDT)
committerEike Stepper2007-09-10 03:38:31 (EDT)
commit4e3446008819292ad0668fcbe2ff44ce35c07356 (patch)
tree127008e28624566095268f47b0725855b49e005a
parent4ee5eedf629e3a5568e3c3f339bf4535ad22adc8 (diff)
downloadcdo-4e3446008819292ad0668fcbe2ff44ce35c07356.zip
cdo-4e3446008819292ad0668fcbe2ff44ce35c07356.tar.gz
cdo-4e3446008819292ad0668fcbe2ff44ce35c07356.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.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/LoadRevisionIndication.java61
-rw-r--r--plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFeatureAnalyzer.java29
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFetchRuleManager.java31
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/validation/CDOResourceValidator.java47
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDORevisionManagerImpl.java8
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java20
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java32
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOClusterOfFetchRule.java122
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleAnalyzer.java210
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleManager.java58
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOFetchFeatureInfo.java84
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraph.java112
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraphAnalyzer.java111
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOReadAhead.java121
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFeatureAnalyzer.java35
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFetchRuleManager.java40
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/LoadRevisionRequest.java40
19 files changed, 1048 insertions, 134 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 8899d95..d15c899 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
@@ -34,7 +34,7 @@ import org.eclipse.net4j.util.lifecycle.ILifecycle;
import java.text.MessageFormat;
import java.util.HashSet;
-import java.util.Map;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -186,8 +186,8 @@ 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,
- Map<CDOID, CDORevisionImpl> containedRevisions)
+ public void collectContainedRevisions(CDORevisionImpl revision, int referenceChunk, Set<CDOID> revisions,
+ List<CDORevisionImpl> additionalRevisions)
{
RevisionManager revisionManager = getSessionManager().getRepository().getRevisionManager();
CDOClassImpl cdoClass = revision.getCDOClass();
@@ -201,14 +201,13 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
if (value instanceof CDOID)
{
CDOID id = (CDOID)value;
- if (!id.isNull())
+ if (!id.isNull() && !revisions.contains(id))
{
- if (containedRevisions.get(id) == null)
- {
- CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
- containedRevisions.put(id, containedRevision);
- collectContainedRevisions(containedRevision, referenceChunk, containedRevisions);
- }
+ CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
+ revisions.add(id);
+ additionalRevisions.add(containedRevision);
+
+ collectContainedRevisions(containedRevision, referenceChunk, revisions, additionalRevisions);
}
}
}
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 79e89d7..042b0e8 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
@@ -28,8 +28,10 @@ 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.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -79,6 +81,8 @@ public class LoadRevisionIndication extends CDOReadIndication
if (fetchSize > 0)
{
contextID = CDOIDImpl.read(in);
+ if (PROTOCOL.isEnabled()) PROTOCOL.format("Reading fetch rules for context {0}", contextID);
+
for (int i = 0; i < fetchSize; i++)
{
CDOFetchRule fetchRule = new CDOFetchRule(in, getPackageManager());
@@ -91,27 +95,31 @@ public class LoadRevisionIndication extends CDOReadIndication
protected void responding(ExtendedDataOutputStream out) throws IOException
{
Session session = getSession();
- Map<CDOID, CDORevisionImpl> containedRevisions = new HashMap<CDOID, CDORevisionImpl>(0);
-
+ List<CDORevisionImpl> additionalRevisions = new ArrayList<CDORevisionImpl>();
+ HashSet<CDOID> revisions = new HashSet<CDOID>();
if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing {0} revisions", ids.length);
+
+ // Need to fetch the rule first.
+ if (!contextID.isNull() && fetchRules.size() > 0)
+ {
+ if (PROTOCOL.isEnabled()) PROTOCOL.format("Collecting more objects based on rules");
+ CDORevisionImpl revisionContext = getRevision(contextID);
+ Set<CDOFetchRule> workingFetchRules = new HashSet<CDOFetchRule>();
+ collectRevisionsByRule(revisionContext, referenceChunk, revisions, additionalRevisions, workingFetchRules);
+ }
+
for (CDOID id : ids)
{
CDORevisionImpl revision = getRevision(id);
revision.write(out, session, referenceChunk);
- session.collectContainedRevisions(revision, referenceChunk, containedRevisions);
+ revisions.add(revision.getID());
+ session.collectContainedRevisions(revision, referenceChunk, revisions, additionalRevisions);
}
- 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(additionalRevisions.size());
+ if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing {0} additional revisions", additionalRevisions.size());
- out.writeInt(containedRevisions.size());
- if (PROTOCOL.isEnabled()) PROTOCOL.format("Writing {0} additional revisions", containedRevisions.size());
- for (CDORevisionImpl revision : containedRevisions.values())
+ for (CDORevisionImpl revision : additionalRevisions)
{
revision.write(out, session, referenceChunk);
}
@@ -122,8 +130,8 @@ public class LoadRevisionIndication extends CDOReadIndication
return getRevisionManager().getRevision(id, referenceChunk);
}
- private void collectRevisionsByRule(CDORevisionImpl revision, int referenceChunk,
- Map<CDOID, CDORevisionImpl> containedRevisions, Set<CDOFetchRule> workingFetchRules)
+ private void collectRevisionsByRule(CDORevisionImpl revision, int referenceChunk, Set<CDOID> revisions,
+ List<CDORevisionImpl> additionalRevisions, Set<CDOFetchRule> workingFetchRules)
{
CDOFetchRule fetchRule = fetchRules.get(revision.getCDOClass());
if (fetchRule == null || workingFetchRules.contains(fetchRule))
@@ -132,6 +140,7 @@ public class LoadRevisionIndication extends CDOReadIndication
}
workingFetchRules.add(fetchRule);
+
RevisionManager revisionManager = getSessionManager().getRepository().getRevisionManager();
for (CDOFeature feature : fetchRule.getFeatures())
{
@@ -145,11 +154,15 @@ public class LoadRevisionIndication extends CDOReadIndication
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);
+ if (!id.isNull() && !revisions.contains(id))
+ {
+ CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
+ revisions.add(containedRevision.getID());
+ additionalRevisions.add(containedRevision);
+
+ collectRevisionsByRule(containedRevision, referenceChunk, revisions, additionalRevisions,
+ workingFetchRules);
+ }
}
}
}
@@ -159,11 +172,13 @@ public class LoadRevisionIndication extends CDOReadIndication
if (value instanceof CDOID)
{
CDOID id = (CDOID)value;
- if (!id.isNull() && !containedRevisions.containsKey(id))
+ if (!id.isNull() && !revisions.contains(id))
{
CDORevisionImpl containedRevision = revisionManager.getRevision(id, referenceChunk);
- containedRevisions.put(containedRevision.getID(), containedRevision);
- collectRevisionsByRule(containedRevision, referenceChunk, containedRevisions, workingFetchRules);
+ revisions.add(containedRevision.getID());
+ additionalRevisions.add(containedRevision);
+
+ collectRevisionsByRule(containedRevision, referenceChunk, revisions, additionalRevisions, workingFetchRules);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
index 06b6f7f..4a87be1 100644
--- a/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo/META-INF/MANIFEST.MF
@@ -13,11 +13,13 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
org.eclipse.emf.ecore.xmi;bundle-version="[2.3.0,3.0.0)",
org.eclipse.emf.cdo.protocol;bundle-version="[0.8.0,0.9.0)";visibility:=reexport
Export-Package: org.eclipse.emf.cdo;version="0.8.0",
+ org.eclipse.emf.cdo.analyzer;version="0.8.0",
org.eclipse.emf.cdo.eresource;version="0.8.0",
org.eclipse.emf.cdo.eresource.impl;version="0.8.0",
org.eclipse.emf.cdo.eresource.util;version="0.8.0",
org.eclipse.emf.cdo.util;version="0.8.0",
org.eclipse.emf.internal.cdo;version="0.8.0",
+ org.eclipse.emf.internal.cdo.analyzer;version="0.8.0",
org.eclipse.emf.internal.cdo.protocol;version="0.8.0",
org.eclipse.emf.internal.cdo.util;version="0.8.0"
Eclipse-LazyStart: true
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFeatureAnalyzer.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFeatureAnalyzer.java
new file mode 100644
index 0000000..2f46b9a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFeatureAnalyzer.java
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.analyzer;
+
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
+import org.eclipse.emf.internal.cdo.InternalCDOObject;
+import org.eclipse.emf.internal.cdo.analyzer.NOOPFeatureAnalyzer;
+
+
+/**
+ * @author Eike Stepper
+ */
+public interface CDOFeatureAnalyzer
+{
+ public static final CDOFeatureAnalyzer NOOP = new NOOPFeatureAnalyzer();
+
+ public void preTraverseFeature(InternalCDOObject revision, CDOFeature feature, int index);
+
+ public void postTraverseFeature(InternalCDOObject revision, CDOFeature feature, int index, Object value);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFetchRuleManager.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFetchRuleManager.java
new file mode 100644
index 0000000..53b9556
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/analyzer/CDOFetchRuleManager.java
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.analyzer;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.internal.cdo.analyzer.NOOPFetchRuleManager;
+
+/**
+ * @author Eike Stepper
+ */
+public interface CDOFetchRuleManager
+{
+ public static final CDOFetchRuleManager NOOP = new NOOPFetchRuleManager();
+
+ public CDOID getContext();
+
+ public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/validation/CDOResourceValidator.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/validation/CDOResourceValidator.java
deleted file mode 100644
index fbd41e6..0000000
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/validation/CDOResourceValidator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * <copyright>
- * </copyright>
- *
- * $Id$
- */
-package org.eclipse.emf.cdo.eresource.validation;
-
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.common.util.URI;
-
-import org.eclipse.emf.ecore.EObject;
-
-import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
-
-import org.eclipse.emf.ecore.resource.ResourceSet;
-
-/**
- * A sample validator interface for
- * {@link org.eclipse.emf.cdo.eresource.CDOResource}. This doesn't really do
- * anything, and it's not a real EMF artifact. It was generated by the
- * org.eclipse.emf.examples.generator.validator plug-in to illustrate how EMF's
- * code generator can be extended. This can be disabled with -vmargs
- * -Dorg.eclipse.emf.examples.generator.validator=false.
- */
-public interface CDOResourceValidator
-{
- boolean validate();
-
- boolean validateResourceSet(ResourceSet value);
-
- boolean validateURI(URI value);
-
- boolean validateContents(EList<EObject> value);
-
- boolean validateModified(boolean value);
-
- boolean validateLoaded(boolean value);
-
- boolean validateTrackingModification(boolean value);
-
- boolean validateErrors(EList<Diagnostic> value);
-
- boolean validateWarnings(EList<Diagnostic> value);
-
- boolean validatePath(String value);
-}
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 c1d2308..57aba9e 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,7 +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.analyzer.CDOFetchRuleManager;
import org.eclipse.emf.cdo.protocol.model.CDOFeature;
import org.eclipse.emf.cdo.protocol.revision.CDOReferenceProxy;
import org.eclipse.emf.cdo.protocol.util.TransportException;
@@ -39,7 +39,7 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C
{
private CDOSessionImpl session;
- private IFetchRuleManager ruleManager = IFetchRuleManager.NOOP;
+ private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP;
public CDORevisionManagerImpl(CDOSessionImpl session)
{
@@ -251,12 +251,12 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C
}
}
- public IFetchRuleManager getRuleManager()
+ public CDOFetchRuleManager getRuleManager()
{
return ruleManager;
}
- public void setRuleManager(IFetchRuleManager ruleManager)
+ public void setRuleManager(CDOFetchRuleManager 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 097b66e..5f63dfb 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
@@ -10,15 +10,16 @@
**************************************************************************/
package org.eclipse.emf.internal.cdo;
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Set;
+
import org.eclipse.emf.cdo.internal.protocol.model.CDOFeatureImpl;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl.MoveableList;
import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.model.CDOFeature;
import org.eclipse.emf.cdo.protocol.revision.CDOReferenceProxy;
-
-import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
-
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
@@ -27,10 +28,7 @@ import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
-
-import java.text.MessageFormat;
-import java.util.HashSet;
-import java.util.Set;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
/**
* @author Eike Stepper
@@ -106,7 +104,7 @@ public final class CDOStore implements EStore
TRACER.format("get({0}, {1}, {2})", cdoObject, cdoFeature, index);
}
- view.getFeatureAnalyzer().preTraverseFeature(cdoObject.cdoRevision(), cdoFeature, index);
+ view.getFeatureAnalyzer().preTraverseFeature(cdoObject, cdoFeature, index);
CDORevisionImpl revision = getRevisionForReading(cdoObject);
Object value = get(revision, cdoFeature, index);
if (cdoFeature.isReference())
@@ -116,11 +114,11 @@ public final class CDOStore implements EStore
CDOID id = (CDOID)value;
loadAhead(revision, cdoFeature, id, index);
}
-
+
value = view.convertIDToObject(value);
}
-
- view.getFeatureAnalyzer().postTraverseFeature(cdoObject.cdoRevision(), cdoFeature, index);
+
+ view.getFeatureAnalyzer().postTraverseFeature(cdoObject, cdoFeature, index, value);
return value;
}
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 9a6ad953..ff15502 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
@@ -13,10 +13,18 @@
**************************************************************************/
package org.eclipse.emf.internal.cdo;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.CDOView;
import org.eclipse.emf.cdo.CDOViewEvent;
import org.eclipse.emf.cdo.CDOViewResourcesEvent;
+import org.eclipse.emf.cdo.analyzer.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.EresourceFactory;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
@@ -25,18 +33,12 @@ 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;
import org.eclipse.emf.cdo.protocol.util.TransportException;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.ReadOnlyException;
-
-import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
-import org.eclipse.net4j.signal.IFailOverStrategy;
-import org.eclipse.net4j.util.ImplementationError;
-
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
@@ -52,13 +54,9 @@ import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.protocol.ResourcePathRequest;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
-
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+import org.eclipse.net4j.signal.IFailOverStrategy;
+import org.eclipse.net4j.util.ImplementationError;
/**
* @author Eike Stepper
@@ -78,7 +76,7 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
private int loadRevisionCollectionChunkSize = 1;
- private IFeatureAnalyzer featureAnalyzer = IFeatureAnalyzer.NOOP;
+ private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP;
private Map<CDOID, InternalCDOObject> objects = new HashMap<CDOID, InternalCDOObject>();
@@ -144,14 +142,14 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier
this.loadRevisionCollectionChunkSize = loadRevisionCollectionChunkSize;
}
- public IFeatureAnalyzer getFeatureAnalyzer()
+ public CDOFeatureAnalyzer getFeatureAnalyzer()
{
return featureAnalyzer;
}
- public void setFeatureAnalyzer(IFeatureAnalyzer featureAnalyzer)
+ public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer)
{
- this.featureAnalyzer = featureAnalyzer == null ? IFeatureAnalyzer.NOOP : featureAnalyzer;
+ this.featureAnalyzer = featureAnalyzer == null ? CDOFeatureAnalyzer.NOOP : featureAnalyzer;
}
public CDOTransactionImpl toTransaction()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOClusterOfFetchRule.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOClusterOfFetchRule.java
new file mode 100644
index 0000000..e48941e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOClusterOfFetchRule.java
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.model.CDOClass;
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOClusterOfFetchRule
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOClusterOfFetchRule.class);
+
+ private Map<CDOFeature, CDOFetchFeatureInfo> featureStats = new HashMap<CDOFeature, CDOFetchFeatureInfo>();
+
+ private Map<CDOClass, CDOFetchRule> fetchRules = new HashMap<CDOClass, CDOFetchRule>();
+
+ private CDOFeature rootFeature;
+
+ private long lastUpdate;
+
+ public CDOClusterOfFetchRule(CDOFeature rootFeature)
+ {
+ this.rootFeature = rootFeature;
+ lastUpdate = System.currentTimeMillis();
+ }
+
+ public boolean isActive()
+ {
+ return !fetchRules.isEmpty();
+ }
+
+ public Iterator<CDOFetchRule> iterator()
+ {
+ return fetchRules.values().iterator();
+ }
+
+ public synchronized CDOFetchFeatureInfo getFeatureStat(CDOFeature cdoFeature)
+ {
+ CDOFetchFeatureInfo featureRule = featureStats.get(cdoFeature);
+ if (featureRule == null)
+ {
+ featureRule = new CDOFetchFeatureInfo();
+ featureStats.put(cdoFeature, featureRule);
+ }
+
+ return featureRule;
+ }
+
+ public synchronized CDOFetchRule addFeatureRule(CDOClass cdoClass, CDOFeature cdoFeature)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adding new fetch rule : {0}.{1} from root feature {2}", cdoClass.getName(), cdoFeature.getName(),
+ rootFeature);
+ }
+
+ lastUpdate = System.currentTimeMillis();
+ CDOFetchRule fetchRule = getFetchRule(cdoClass);
+ fetchRule.addFeature(cdoFeature);
+ return fetchRule;
+ }
+
+ public synchronized CDOFetchRule removeFeatureRule(CDOClass cdoClass, CDOFeature cdoFeature)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removing fetch rule : {0}.{1} from root feature {2}", cdoClass.getName(), cdoFeature.getName(),
+ rootFeature);
+ }
+
+ lastUpdate = System.currentTimeMillis();
+
+ CDOFetchRule fetchRule = getFetchRule(cdoClass);
+ fetchRule.removeFeature(cdoFeature);
+ if (fetchRule.isEmpty())
+ {
+ fetchRules.remove(cdoClass);
+ }
+
+ return fetchRule;
+ }
+
+ public synchronized CDOFetchRule getFetchRule(CDOClass cdoFeature)
+ {
+ CDOFetchRule featureRule = fetchRules.get(cdoFeature);
+ if (featureRule == null)
+ {
+ featureRule = new CDOFetchRule(cdoFeature);
+ fetchRules.put(cdoFeature, featureRule);
+ }
+
+ return featureRule;
+ }
+
+ public long getLastUpdate()
+ {
+ return lastUpdate;
+ }
+
+ public CDOFeature getRootFeature()
+ {
+ return rootFeature;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleAnalyzer.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleAnalyzer.java
new file mode 100644
index 0000000..864a9d0
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleAnalyzer.java
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.analyzer.CDOFeatureAnalyzer;
+import org.eclipse.emf.cdo.analyzer.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.cdo.protocol.model.CDOClass;
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
+import org.eclipse.emf.internal.cdo.InternalCDOObject;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.util.FSMUtil;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDODynamicFetchRuleAnalyzer implements CDOFeatureAnalyzer, CDOFetchRuleManager
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDODynamicFetchRuleAnalyzer.class);
+
+ private static final long ELAPSE_TIME = 400L;
+
+ private Map<CDOFeature, CDOClusterOfFetchRule> featureRules = new HashMap<CDOFeature, CDOClusterOfFetchRule>();
+
+ private CDOGraphAnalyzer graphAnalyzer = new CDOGraphAnalyzer();
+
+ private CDOGraph currentGraph;
+
+ private long lastAccessTime;
+
+ private boolean inUse;
+
+ private InternalCDOObject lastRevision;
+
+ private CDOView view;
+
+ private boolean doesFetch;
+
+ public CDODynamicFetchRuleAnalyzer(CDOView view)
+ {
+ this.view = view;
+ }
+
+ public CDOClusterOfFetchRule getCurrentFeatureRule()
+ {
+ return currentGraph.getFeatureRule();
+ }
+
+ public CDOGraph getCurrentGraph()
+ {
+ return currentGraph;
+ }
+
+ public void preTraverseFeature(InternalCDOObject cdoObject, CDOFeature feature, int index)
+ {
+ CDOClass cdoClass = cdoObject.cdoClass();
+ doesFetch = false;
+ CDODynamicFetchRuleManager.join(this);
+ lastRevision = cdoObject;
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("preTraverseFeature : {0}.{1}", cdoClass.getName(), feature.getName());
+ }
+
+ // Do not handle these cases
+ long currentTime = System.currentTimeMillis();
+ long elapseTimeBeforeLastRequest = currentTime - lastAccessTime;
+ lastAccessTime = currentTime;
+
+ // Don`t handle containment relationship
+ if (!feature.isReference())
+ {
+ return;
+ }
+
+ if (elapseTimeBeforeLastRequest > ELAPSE_TIME)
+ {
+ graphAnalyzer.clear();
+ }
+
+ // Purge old graph that we didn't update for specific elapse time
+ graphAnalyzer.purge(ELAPSE_TIME * 2, ELAPSE_TIME * 2);
+
+ CDOClusterOfFetchRule featureRule = getFeatureRule(cdoClass, feature);
+
+ // Get the graph <cdoObject> belongs to
+ currentGraph = graphAnalyzer.getGraph(cdoObject.cdoID(), featureRule);
+ lastAccessTime = System.currentTimeMillis();
+
+ if (currentGraph.getFeatureRule().getRootFeature() == feature)
+ {
+ if (graphAnalyzer.isTimeToRemove(currentGraph, lastAccessTime, ELAPSE_TIME))
+ {
+ // Clean it!!
+ currentGraph.clean();
+ return;
+ }
+ }
+
+ // need to calculate currentFeature to calculate the connected graph
+ if (feature.isMany() && index != 0)
+ {
+ return;
+ }
+
+ // Get the cluster of rule for that feature
+ CDOClusterOfFetchRule currentFeatureRule = currentGraph.getFeatureRule();
+ CDOFetchFeatureInfo infoOfFeature = currentFeatureRule.getFeatureStat(feature);
+ infoOfFeature.updateTimeInfo(elapseTimeBeforeLastRequest);
+
+ // Detect a new rule
+ if (!infoOfFeature.isActive() && infoOfFeature.getTimeBeforeUsed() < ELAPSE_TIME)
+ {
+ currentFeatureRule.addFeatureRule(cdoClass, feature);
+ infoOfFeature.setActive(true);
+ }
+
+ // Detect if the rule is still good!
+ else if (infoOfFeature.isActive() && infoOfFeature.getTimeBeforeUsed() > ELAPSE_TIME)
+ {
+ // Unregister rules
+ currentFeatureRule.removeFeatureRule(cdoClass, feature);
+ infoOfFeature.setActive(false);
+ }
+
+ lastAccessTime = currentTime;
+ inUse = true;
+ }
+
+ public void postTraverseFeature(InternalCDOObject cdoObject, CDOFeature feature, int index, Object object)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("postTraverseFeature : {0}.{1}", cdoObject.cdoClass(), feature.getName());
+ }
+
+ if (currentGraph != null)
+ {
+ // Adding return object to the link graph
+ InternalCDOObject destObject = FSMUtil.adapt(object, view);
+ currentGraph.add(cdoObject.cdoID(), feature, destObject.cdoID());
+
+ // calculate latency time
+ if (doesFetch == true)
+ {
+ CDOClusterOfFetchRule currentFeatureRule = currentGraph.getFeatureRule();
+ CDOFetchFeatureInfo infoOfFeature = currentFeatureRule.getFeatureStat(feature);
+ infoOfFeature.updateLatencyTime(System.currentTimeMillis() - lastAccessTime);
+ }
+ }
+
+ lastAccessTime = System.currentTimeMillis();
+ inUse = false;
+ CDODynamicFetchRuleManager.leave();
+ }
+
+ public CDOID getContext()
+ {
+ return lastRevision.cdoID();
+ }
+
+ public synchronized CDOClusterOfFetchRule getFeatureRule(CDOClass cdoClass, CDOFeature cdoFeature)
+ {
+ CDOClusterOfFetchRule featureRule = featureRules.get(cdoFeature);
+ if (featureRule == null)
+ {
+ featureRule = new CDOClusterOfFetchRule(cdoFeature);
+ featureRules.put(cdoFeature, featureRule);
+ }
+
+ return featureRule;
+ }
+
+ public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids)
+ {
+ doesFetch = true;
+ if (!inUse || currentGraph == null)
+ {
+ return null;
+ }
+
+ List<CDOFetchRule> list = new ArrayList<CDOFetchRule>();
+ for (Iterator<CDOFetchRule> it = currentGraph.getFeatureRule().iterator(); it.hasNext();)
+ {
+ CDOFetchRule fetchRule = it.next();
+ list.add(fetchRule);
+ }
+
+ return list;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleManager.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleManager.java
new file mode 100644
index 0000000..e194f59
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDODynamicFetchRuleManager.java
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import org.eclipse.emf.cdo.analyzer.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.CDOID;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDODynamicFetchRuleManager implements CDOFetchRuleManager
+{
+ private static final ThreadLocal<CDOFetchRuleManager> threadLocal = new ThreadLocal<CDOFetchRuleManager>();
+
+ public CDODynamicFetchRuleManager()
+ {
+ }
+
+ public static void join(CDOFetchRuleManager fetchRulemanager)
+ {
+ threadLocal.set(fetchRulemanager);
+ }
+
+ public static CDOFetchRuleManager getCurrent()
+ {
+ return threadLocal.get();
+ }
+
+ public static void leave()
+ {
+ threadLocal.set(null);
+ }
+
+ public CDOID getContext()
+ {
+ CDOFetchRuleManager analyzer = CDODynamicFetchRuleManager.getCurrent();
+ return analyzer != null ? analyzer.getContext() : null;
+ }
+
+ public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids)
+ {
+ CDOFetchRuleManager analyzer = CDODynamicFetchRuleManager.getCurrent();
+ return analyzer != null ? analyzer.getFetchRules(ids) : null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOFetchFeatureInfo.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOFetchFeatureInfo.java
new file mode 100644
index 0000000..fba9612
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOFetchFeatureInfo.java
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOFetchFeatureInfo
+{
+ private long timeBeforeUsed;
+
+ private long latencyTime;
+
+ private boolean active;
+
+ public CDOFetchFeatureInfo()
+ {
+ active = false;
+ latencyTime = -1;
+ }
+
+ public boolean isActive()
+ {
+ return active;
+ }
+
+ public void setActive(boolean isActive)
+ {
+ active = isActive;
+ }
+
+ public long getTimeBeforeUsed()
+ {
+ return timeBeforeUsed;
+ }
+
+ public void setTimeBeforeUsed(long timeBeforeUsed)
+ {
+ this.timeBeforeUsed = timeBeforeUsed;
+ }
+
+ public long getLatencyTime()
+ {
+ return latencyTime;
+ }
+
+ public void setLatencyTime(long latencyTime)
+ {
+ this.latencyTime = latencyTime;
+ }
+
+ public void updateLatencyTime(long latencyTime)
+ {
+ if (getLatencyTime() == -1)
+ {
+ setLatencyTime(latencyTime);
+ }
+ else
+ {
+ setLatencyTime((latencyTime + getLatencyTime()) / 2);
+ }
+ }
+
+ public void updateTimeInfo(long elapseTimeBeforeLastRequest)
+ {
+ if (getTimeBeforeUsed() == 0)
+ {
+ setTimeBeforeUsed(elapseTimeBeforeLastRequest);
+ }
+ else
+ {
+ setTimeBeforeUsed((getTimeBeforeUsed() + elapseTimeBeforeLastRequest) / 2);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraph.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraph.java
new file mode 100644
index 0000000..964ed37
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraph.java
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOGraph
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOGraph.class);
+
+ private CDOGraphAnalyzer analyzer;
+
+ private CDOClusterOfFetchRule featureRule;
+
+ private List<CDOID> clusterOfObjects = new ArrayList<CDOID>();
+
+ private long lastUpdated;
+
+ private long creationTime;
+
+ public CDOGraph(CDOGraphAnalyzer analyzer, CDOID rootID, CDOClusterOfFetchRule featureRule)
+ {
+ this.analyzer = analyzer;
+ this.featureRule = featureRule;
+ // Adding the root element
+ add(rootID, null, rootID);
+ creationTime = System.currentTimeMillis();
+ }
+
+ public List<CDOID> getObjects()
+ {
+ return clusterOfObjects;
+ }
+
+ public CDOClusterOfFetchRule getFeatureRule()
+ {
+ return featureRule;
+ }
+
+ public long getLastUpdated()
+ {
+ return lastUpdated;
+ }
+
+ public long getCreationTime()
+ {
+ return creationTime;
+ }
+
+ public CDOID getRoot()
+ {
+ return getObjects().get(0);
+ }
+
+ public void clean()
+ {
+ Iterator<CDOID> itr = clusterOfObjects.iterator();
+ itr.next(); // Skip the Root!
+ while (itr.hasNext())
+ {
+ analyzer.removeTrackingID(itr.next());
+ }
+
+ creationTime = System.currentTimeMillis();
+ }
+
+ public void update()
+ {
+ lastUpdated = System.currentTimeMillis();
+ }
+
+ public void add(CDOID fromID, CDOFeature feature, CDOID id)
+ {
+ // For now .. we do not need to calculate the path.. later we will do!!
+ clusterOfObjects.add(id);
+ analyzer.addTrackingID(id, this);
+ }
+
+ public void remove()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removing CDOGraph {0}", this);
+ }
+
+ for (CDOID id : clusterOfObjects)
+ {
+ analyzer.removeTrackingID(id);
+ }
+
+ analyzer.removeTracking(this);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraphAnalyzer.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraphAnalyzer.java
new file mode 100644
index 0000000..3265c24
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOGraphAnalyzer.java
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOGraphAnalyzer
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOGraphAnalyzer.class);
+
+ private Map<CDOID, CDOGraph> idToGraphMap = new HashMap<CDOID, CDOGraph>();
+
+ private HashSet<CDOGraph> uniqueGraphs = new HashSet<CDOGraph>();
+
+ private long lastPurgeOperation;
+
+ public CDOGraphAnalyzer()
+ {
+ lastPurgeOperation = System.currentTimeMillis();
+ }
+
+ public CDOGraph getGraph(CDOID fromID, CDOClusterOfFetchRule featureRule)
+ {
+ CDOGraph graph = idToGraphMap.get(fromID);
+ if (graph == null)
+ {
+ graph = new CDOGraph(this, fromID, featureRule);
+ uniqueGraphs.add(graph);
+ }
+
+ // Update is time value
+ graph.update();
+ return graph;
+ }
+
+ public void purge(long elapseTimeForPurging, long elapseTimeToClear)
+ {
+ long time = System.currentTimeMillis();
+ if (time - lastPurgeOperation > elapseTimeForPurging)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Purging graph {0}", this);
+ }
+
+ ArrayList<CDOGraph> listToRemove = new ArrayList<CDOGraph>();
+ for (CDOGraph graph : uniqueGraphs)
+ {
+ if (isTimeToRemove(graph, time, elapseTimeToClear))
+ {
+ listToRemove.add(graph);
+ }
+ }
+
+ for (CDOGraph graph : listToRemove)
+ {
+ graph.remove();
+ }
+
+ lastPurgeOperation = System.currentTimeMillis();
+ }
+ }
+
+ public boolean isTimeToRemove(CDOGraph graph, long currentTimestamp, long elapseTimeToClear)
+ {
+ return currentTimestamp - graph.getLastUpdated() > elapseTimeToClear
+ || currentTimestamp - graph.getFeatureRule().getLastUpdate() > elapseTimeToClear
+ && currentTimestamp - graph.getCreationTime() > elapseTimeToClear;
+ }
+
+ public void addTrackingID(CDOID id, CDOGraph graph)
+ {
+ idToGraphMap.put(id, graph);
+ graph.update();
+ }
+
+ public void removeTrackingID(CDOID id)
+ {
+ idToGraphMap.remove(id);
+ }
+
+ public void removeTracking(CDOGraph graph)
+ {
+ uniqueGraphs.remove(graph);
+ }
+
+ public void clear()
+ {
+ idToGraphMap.clear();
+ uniqueGraphs.clear();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOReadAhead.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOReadAhead.java
new file mode 100644
index 0000000..847b3b0
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/CDOReadAhead.java
@@ -0,0 +1,121 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import org.eclipse.emf.cdo.analyzer.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.CDOID;
+
+import org.eclipse.net4j.internal.util.concurrent.QueueWorkerWorkSerializer;
+import org.eclipse.net4j.util.concurrent.IWorkSerializer;
+
+import org.eclipse.emf.internal.cdo.CDOSessionImpl;
+import org.eclipse.emf.internal.cdo.CDOViewImpl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOReadAhead
+{
+ private IWorkSerializer workSerializer = new QueueWorkerWorkSerializer();
+
+ private CDOViewImpl view;
+
+ public CDOReadAhead(CDOViewImpl view)
+ {
+ this.view = view;
+ }
+
+ public CDOViewImpl getView()
+ {
+ return view;
+ }
+
+ public void addIDs(Set<CDOID> ids)
+ {
+ CDODynamicFetchRuleAnalyzer dynamic = (CDODynamicFetchRuleAnalyzer)getView().getFeatureAnalyzer();
+ if (dynamic.getCurrentGraph().getFeatureRule().isActive())
+ {
+ workSerializer.addWork(new ReceiverWork(ids));
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class ReceiverWork implements Runnable
+ {
+ private Set<CDOID> ids;
+
+ private CDODynamicFetchRuleAnalyzer dynamic;
+
+ private CDOGraph graph;
+
+ private CDOID context;
+
+ /**
+ * TODO Remove?
+ */
+ private Test test = new Test();
+
+ private ReceiverWork(Set<CDOID> ids)
+ {
+ this.ids = ids;
+ dynamic = (CDODynamicFetchRuleAnalyzer)getView().getFeatureAnalyzer();
+ graph = dynamic.getCurrentGraph();
+ context = dynamic.getContext();
+ }
+
+ public void run()
+ {
+ CDODynamicFetchRuleManager.join(test);
+ CDOSessionImpl s = getView().getSession();
+ s.getRevisionManager().getRevisions(ids, s.getReferenceChunkSize());
+ }
+
+ /**
+ * TODO Remove?
+ *
+ * @author Eike Stepper
+ */
+ @Deprecated
+ private final class Test implements CDOFetchRuleManager
+ {
+ public Test()
+ {
+ }
+
+ public CDOID getContext()
+ {
+ return context;
+ }
+
+ public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids)
+ {
+ List<CDOFetchRule> list = new ArrayList<CDOFetchRule>();
+ for (Iterator<CDOFetchRule> it = graph.getFeatureRule().iterator(); it.hasNext();)
+ {
+ CDOFetchRule fetchRule = it.next();
+ list.add(fetchRule);
+ }
+
+ return list;
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFeatureAnalyzer.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFeatureAnalyzer.java
new file mode 100644
index 0000000..0f71bf9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFeatureAnalyzer.java
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import org.eclipse.emf.cdo.analyzer.CDOFeatureAnalyzer;
+import org.eclipse.emf.cdo.protocol.model.CDOFeature;
+import org.eclipse.emf.internal.cdo.InternalCDOObject;
+
+
+/**
+ * @author Eike Stepper
+ */
+public class NOOPFeatureAnalyzer implements CDOFeatureAnalyzer
+{
+ public NOOPFeatureAnalyzer()
+ {
+ }
+
+ public void preTraverseFeature(InternalCDOObject cdoClass, CDOFeature feature, int index)
+ {
+ }
+
+ public void postTraverseFeature(InternalCDOObject cdoClass, CDOFeature feature, int index, Object value)
+ {
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFetchRuleManager.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFetchRuleManager.java
new file mode 100644
index 0000000..3ba37ac
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/analyzer/NOOPFetchRuleManager.java
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.analyzer;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.cdo.analyzer.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.internal.protocol.CDOIDNull;
+import org.eclipse.emf.cdo.internal.protocol.analyzer.CDOFetchRule;
+import org.eclipse.emf.cdo.protocol.CDOID;
+
+/**
+ * @author Eike Stepper
+ */
+public class NOOPFetchRuleManager implements CDOFetchRuleManager
+{
+ public NOOPFetchRuleManager()
+ {
+ }
+
+ public CDOID getContext()
+ {
+ return CDOIDNull.NULL;
+ }
+
+ public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids)
+ {
+ return null;
+ }
+}
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 f32846b..4817d77 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
@@ -10,28 +10,26 @@
**************************************************************************/
package org.eclipse.emf.internal.cdo.protocol;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.cdo.analyzer.CDOFetchRuleManager;
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;
-import org.eclipse.net4j.util.io.ExtendedDataInputStream;
-import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
-
import org.eclipse.emf.internal.cdo.CDORevisionManagerImpl;
import org.eclipse.emf.internal.cdo.CDOSessionImpl;
import org.eclipse.emf.internal.cdo.CDOSessionPackageManager;
import org.eclipse.emf.internal.cdo.bundle.OM;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import org.eclipse.net4j.IChannel;
+import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
+import org.eclipse.net4j.util.io.ExtendedDataInputStream;
+import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
/**
* @author Eike Stepper
@@ -77,24 +75,22 @@ public class LoadRevisionRequest extends CDOClientRequest<List<CDORevisionImpl>>
CDOIDImpl.write(out, id);
}
- IFetchRuleManager ruleManager = getSession().getRevisionManager().getRuleManager();
+ CDOFetchRuleManager ruleManager = getSession().getRevisionManager().getRuleManager();
List<CDOFetchRule> fetchRules = ruleManager.getFetchRules(ids);
- if (fetchRules == null || fetchRules.size() == 0)
+ if (fetchRules == null || fetchRules.size() <= 0)
{
out.writeInt(0);
}
else
{
+ // At this point, fetch size is more than one.
int fetchSize = fetchRules.size();
out.writeInt(fetchSize);
- if (fetchSize > 0)
+ CDOID contextID = ruleManager.getContext();
+ CDOIDImpl.write(out, contextID);
+ for (CDOFetchRule fetchRule : fetchRules)
{
- CDOID contextID = ruleManager.getContext();
- CDOIDImpl.write(out, contextID);
- for (CDOFetchRule fetchRule : fetchRules)
- {
- fetchRule.write(out);
- }
+ fetchRule.write(out);
}
}
}