Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEsteban Dugueperoux2014-07-10 11:37:29 +0000
committerEike Stepper2014-12-20 05:24:35 +0000
commitf02b99712d10f23bc7b11b617621669017b2f243 (patch)
tree15029493db4495a9098456f13f23fddd1a205f50
parent58844da05c944cc00220ab4a35924fa83e60a24e (diff)
downloadcdo-change/29794/20.tar.gz
cdo-change/29794/20.tar.xz
cdo-change/29794/20.zip
[439337] Have CDOLockState prefetch to improve loading time change/29794/20
- Have CDOLockState prefetch to improve loading time when an EContentAdapter exists on the ResourceSet. - Bugzilla_439337_Test added to the suite to test CDOLockState prefetch. - CDOView.options().isLockStatePrefetchEnabled()/setLockStatePrefetchEnabled() new option has been added to the API to allow CDOLockStates prefetch. - org.eclipse.emf.cdo.common.revision.CDORevisionsLoadedEvent has been added in API to be notified of new CDORevision loaded from RevisionLoader. - The difficulty is to have CDOViewImpl.objects cache filled before updating the CDOViewImpl.lockStates cache. Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=439337 Change-Id: I061d91b30f732f8d67eaeb6215b4039e36d73f2d Signed-off-by: Esteban Dugueperoux <esteban.dugueperoux@obeo.fr> Signed-off-by: Eike Stepper <stepper@esc-net.de>
-rw-r--r--plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF68
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionsLoadedEvent.java33
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java62
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_439337_Test.java203
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDODefaultLockStateLoadingPolicy.java29
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLockStateLoadingPolicy.java39
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java42
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java151
10 files changed, 615 insertions, 36 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
index f43900e3b2..3c0340ef51 100644
--- a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.emf.cdo.common
-Bundle-Version: 4.3.100.qualifier
+Bundle-Version: 4.4.0.qualifier
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -14,21 +14,21 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)";visibili
org.eclipse.emf.ecore.change;bundle-version="[2.5.0,3.0.0)";visibility:=reexport,
org.eclipse.emf.ecore.xmi;bundle-version="[2.5.0,3.0.0)";visibility:=reexport,
org.eclipse.net4j.util;bundle-version="[3.0.0,4.0.0)";visibility:=reexport
-Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
- org.eclipse.emf.cdo.common.admin;version="4.3.100",
- org.eclipse.emf.cdo.common.branch;version="4.3.100",
- org.eclipse.emf.cdo.common.commit;version="4.3.100",
- org.eclipse.emf.cdo.common.commit.handler;version="4.3.100",
- org.eclipse.emf.cdo.common.id;version="4.3.100",
- org.eclipse.emf.cdo.common.lob;version="4.3.100",
- org.eclipse.emf.cdo.common.lock;version="4.3.100",
- org.eclipse.emf.cdo.common.model;version="4.3.100",
- org.eclipse.emf.cdo.common.protocol;version="4.3.100",
- org.eclipse.emf.cdo.common.revision;version="4.3.100",
- org.eclipse.emf.cdo.common.revision.delta;version="4.3.100",
- org.eclipse.emf.cdo.common.security;version="4.3.100",
- org.eclipse.emf.cdo.common.util;version="4.3.100",
- org.eclipse.emf.cdo.internal.common;version="4.3.100";
+Export-Package: org.eclipse.emf.cdo.common;version="4.4.0",
+ org.eclipse.emf.cdo.common.admin;version="4.4.0",
+ org.eclipse.emf.cdo.common.branch;version="4.4.0",
+ org.eclipse.emf.cdo.common.commit;version="4.4.0",
+ org.eclipse.emf.cdo.common.commit.handler;version="4.4.0",
+ org.eclipse.emf.cdo.common.id;version="4.4.0",
+ org.eclipse.emf.cdo.common.lob;version="4.4.0",
+ org.eclipse.emf.cdo.common.lock;version="4.4.0",
+ org.eclipse.emf.cdo.common.model;version="4.4.0",
+ org.eclipse.emf.cdo.common.protocol;version="4.4.0",
+ org.eclipse.emf.cdo.common.revision;version="4.4.0",
+ org.eclipse.emf.cdo.common.revision.delta;version="4.4.0",
+ org.eclipse.emf.cdo.common.security;version="4.4.0",
+ org.eclipse.emf.cdo.common.util;version="4.4.0",
+ org.eclipse.emf.cdo.internal.common;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -38,11 +38,11 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests,
org.eclipse.emf.cdo.server.hibernate",
- org.eclipse.emf.cdo.internal.common.branch;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.branch;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.tests,
org.eclipse.emf.cdo.server.hibernate",
- org.eclipse.emf.cdo.internal.common.bundle;version="4.3.100";x-internal:=true,
- org.eclipse.emf.cdo.internal.common.commit;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.bundle;version="4.4.0";x-internal:=true,
+ org.eclipse.emf.cdo.internal.common.commit;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -51,7 +51,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.internal.common.id;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.id;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -62,9 +62,9 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.tests,
org.eclipse.emf.cdo.admin,
org.eclipse.emf.cdo.server.admin",
- org.eclipse.emf.cdo.internal.common.lock;version="4.3.100";x-internal:=true,
- org.eclipse.emf.cdo.internal.common.messages;version="4.3.100";x-internal:=true,
- org.eclipse.emf.cdo.internal.common.model;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.lock;version="4.4.0";x-internal:=true,
+ org.eclipse.emf.cdo.internal.common.messages;version="4.4.0";x-internal:=true,
+ org.eclipse.emf.cdo.internal.common.model;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -73,7 +73,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.internal.common.revision;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.revision;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -82,7 +82,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.internal.common.revision.delta;version="4.3.100";
+ org.eclipse.emf.cdo.internal.common.revision.delta;version="4.4.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
org.eclipse.emf.cdo,
@@ -91,12 +91,12 @@ Export-Package: org.eclipse.emf.cdo.common;version="4.3.100",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
- org.eclipse.emf.cdo.spi.common;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.admin;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.branch;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.commit;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.id;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.lock;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.model;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.protocol;version="4.3.100",
- org.eclipse.emf.cdo.spi.common.revision;version="4.3.100"
+ org.eclipse.emf.cdo.spi.common;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.admin;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.branch;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.commit;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.id;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.lock;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.model;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.protocol;version="4.4.0",
+ org.eclipse.emf.cdo.spi.common.revision;version="4.4.0"
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
index 6c8fe226ae..b87b81e235 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
@@ -18,6 +18,8 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.net4j.util.event.INotifier;
+
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
@@ -51,7 +53,7 @@ import java.util.List;
* @apiviz.has {@link CDORevisionCache}
* @apiviz.uses {@link CDORevision} - - loads
*/
-public interface CDORevisionManager
+public interface CDORevisionManager extends INotifier
{
/**
* Returns the {@link CDORevision#getEClass() type} of an object if a revision for that object is in the revision
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionsLoadedEvent.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionsLoadedEvent.java
new file mode 100644
index 0000000000..a0a83b63e9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionsLoadedEvent.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2004-2014 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Esteban Dugueperoux - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.revision;
+
+import org.eclipse.net4j.util.event.IEvent;
+
+import java.util.List;
+
+/**
+ * An {@link IEvent event} fired from a {@link CDORevisionManager revision manager} when a new {@link CDORevision revision} has
+ * been loaded.
+ *
+ * @author Esteban Dugueperoux
+ * @since 4.4
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface CDORevisionsLoadedEvent extends IEvent
+{
+ public CDORevisionManager getSource();
+
+ public List<? extends CDORevision> getPrimaryLoadedRevisions();
+
+ public List<? extends CDORevision> getAdditionalLoadedRevisions();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
index c4be7fc240..5e7007a3b5 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
@@ -21,7 +21,9 @@ import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionCache;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevisionsLoadedEvent;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
@@ -33,6 +35,7 @@ import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+import org.eclipse.net4j.util.event.Event;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -290,7 +293,27 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
List<RevisionInfo> infosToLoad = createRevisionInfos(ids, branchPoint, prefetchDepth, loadOnDemand, infos);
if (infosToLoad != null)
{
- loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);
+ List<? extends CDORevision> additionalLoadedRevisions //
+ = loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);
+
+ List<? extends CDORevision> primaryLoadedRevisions //
+ = getResultsAndSynthetics(infosToLoad.toArray(new RevisionInfo[infosToLoad.size()]), null);
+
+ if (primaryLoadedRevisions != null && !primaryLoadedRevisions.isEmpty() || additionalLoadedRevisions != null
+ && !additionalLoadedRevisions.isEmpty())
+ {
+ if (primaryLoadedRevisions == null)
+ {
+ primaryLoadedRevisions = Collections.emptyList();
+ }
+
+ if (additionalLoadedRevisions == null)
+ {
+ additionalLoadedRevisions = Collections.emptyList();
+ }
+
+ fireEvent(new RevisionsLoadedEvent(this, primaryLoadedRevisions, additionalLoadedRevisions));
+ }
}
return getResultsAndSynthetics(infos, synthetics);
@@ -554,4 +577,41 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
// Reached main branch
return null;
}
+
+ /**
+ * @author Esteban Dugueperoux
+ */
+ private static class RevisionsLoadedEvent extends Event implements CDORevisionsLoadedEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private List<? extends CDORevision> primaryLoadedRevisions;
+
+ private List<? extends CDORevision> additionalLoadedRevisions;
+
+ public RevisionsLoadedEvent(CDORevisionManager revisionManager, List<? extends CDORevision> primaryLoadedRevisions,
+ List<? extends CDORevision> additionalLoadedRevisions)
+ {
+ super(revisionManager);
+ this.primaryLoadedRevisions = primaryLoadedRevisions;
+ this.additionalLoadedRevisions = additionalLoadedRevisions;
+ }
+
+ @Override
+ public CDORevisionManager getSource()
+ {
+ return (CDORevisionManager)super.getSource();
+ }
+
+ public List<? extends CDORevision> getPrimaryLoadedRevisions()
+ {
+ return primaryLoadedRevisions;
+ }
+
+ public List<? extends CDORevision> getAdditionalLoadedRevisions()
+ {
+ return additionalLoadedRevisions;
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
index 76c298f4eb..c10911cb2d 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
@@ -48,6 +48,7 @@ import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
+import org.eclipse.emf.cdo.view.CDOLockStateLoadingPolicy;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOView;
@@ -371,11 +372,30 @@ public class ServerCDOView extends AbstractCDOView implements org.eclipse.emf.cd
return false;
}
+ public boolean isLockStatePrefetchEnabled()
+ {
+ return false;
+ }
+
public void setLockNotificationEnabled(boolean enabled)
{
throw new UnsupportedOperationException();
}
+ public CDOLockStateLoadingPolicy getLockStateLoadingPolicy()
+ {
+ return null;
+ }
+
+ public void setLockStateLoadingPolicy(CDOLockStateLoadingPolicy lockStateLoadingPolicy)
+ {
+ }
+
+ public void setLockStatePrefetchEnabled(boolean enabled)
+ {
+ throw new UnsupportedOperationException();
+ }
+
public CDOAdapterPolicy[] getChangeSubscriptionPolicies()
{
return ADAPTER_POLICIES;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_439337_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_439337_Test.java
new file mode 100644
index 0000000000..9183a5dd69
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_439337_Test.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2014 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Esteban Dugueperoux - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.net4j.protocol.CDOClientProtocol;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.model1.Category;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.internal.cdo.session.DelegatingSessionProtocol;
+
+import org.eclipse.net4j.signal.Signal;
+import org.eclipse.net4j.signal.SignalScheduledEvent;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
+import org.eclipse.emf.spi.cdo.InternalCDOSession;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Bug 439337 about {@link CDOLockState lock state} prefetch following a {@link CDORevision revision} prefetch.
+ *
+ * @author Esteban Dugueperoux
+ */
+public class Bugzilla_439337_Test extends AbstractCDOTest
+{
+ private static final String RESOURCE_NAME = "test1.model1";
+
+ private static final int NB_CATEGORIES = 10;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+
+ CDOResource resource = transaction.getOrCreateResource(getResourcePath(RESOURCE_NAME));
+ Company company = getModel1Factory().createCompany();
+ for (int i = 0; i < NB_CATEGORIES; i++)
+ {
+ Category category = getModel1Factory().createCategory();
+ category.setName("Category n°" + i);
+ company.getCategories().add(category);
+ }
+ resource.getContents().add(company);
+ transaction.commit();
+ }
+
+ /**
+ * Test {@link CDOLockState} API without prefetch.
+ */
+ public void testCDOLockStateWithoutPrefetch() throws Exception
+ {
+ CDOSession session = openSession();
+ CDOView view = session.openView();
+ testCDOLockState(view, false);
+ }
+
+ /**
+ * Test {@link CDOLockState} API with prefetch.
+ */
+ public void testCDOLockStateWithPrefetch() throws Exception
+ {
+ CDOSession session = openSession();
+ CDOView view = session.openView();
+ view.options().setLockStatePrefetchEnabled(true);
+ testCDOLockState(view, true);
+ }
+
+ private void testCDOLockState(CDOView view, boolean cdoLockStatePrefetchEnabled)
+ {
+ view.getResourceSet().eAdapters().add(new EContentAdapterQueringCDOLockState());
+ NBRequestsCallsCounter nbRequestsCallsCounter = new NBRequestsCallsCounter(view);
+ view.getResource(getResourcePath(RESOURCE_NAME + "?" + CDOResource.PREFETCH_PARAMETER + "=" + Boolean.TRUE));
+
+ Map<Short, Integer> nbRequestsCalls = nbRequestsCallsCounter.getNBRequestsCalls();
+ String assertMessage = "4 differents kinds of requests should have been sent, QueryRequest, QueryCancel, LoadRevisionsRequest and LockStateRequest";
+ // QueryRequest, QueryCancel are used to get the resourcePath
+ assertEquals(assertMessage, 4, nbRequestsCalls.size());
+ assertEquals(true, nbRequestsCalls.containsKey(CDOProtocolConstants.SIGNAL_QUERY));
+ assertEquals(true, nbRequestsCalls.containsKey(CDOProtocolConstants.SIGNAL_QUERY_CANCEL));
+ assertEquals(true, nbRequestsCalls.containsKey(CDOProtocolConstants.SIGNAL_LOAD_REVISIONS));
+ assertEquals(true, nbRequestsCalls.containsKey(CDOProtocolConstants.SIGNAL_LOCK_STATE));
+ assertEquals("1 single query request should have been sent to get the resourcePath", Integer.valueOf(1),
+ nbRequestsCalls.get(CDOProtocolConstants.SIGNAL_QUERY));
+ assertEquals("1 single query request should have been sent to cancel the single QueryRequest", Integer.valueOf(1),
+ nbRequestsCalls.get(CDOProtocolConstants.SIGNAL_QUERY_CANCEL));
+ assertEquals(
+ "3 load revisions request should have been sent, 2 first for CDORevisions of CDOResourceFolders to get resource path and another in prefetch to load all CDORevisions of CDOResource",
+ Integer.valueOf(3), nbRequestsCalls.get(CDOProtocolConstants.SIGNAL_LOAD_REVISIONS));
+ Integer expectedNbLockStateRequestCalls = Integer.valueOf((cdoLockStatePrefetchEnabled ? 0 : NB_CATEGORIES) + 2);
+ assertEquals("As CDOLockState prefetch is " + (cdoLockStatePrefetchEnabled ? "" : "not ") + "enabled "
+ + expectedNbLockStateRequestCalls + " LockStateRequests should have been sent to the server",
+ expectedNbLockStateRequestCalls, nbRequestsCalls.get(CDOProtocolConstants.SIGNAL_LOCK_STATE));
+ }
+
+ /**
+ * {@link IListener} to count sent request and their number.
+ */
+ private static class NBRequestsCallsCounter implements IListener
+ {
+ private Map<Short, Integer> nbRequestsCalls = new HashMap<Short, Integer>();
+
+ public NBRequestsCallsCounter(CDOView view)
+ {
+
+ InternalCDOSession internalCDOSession = (InternalCDOSession)view.getSession();
+ CDOSessionProtocol sessionProtocol = internalCDOSession.getSessionProtocol();
+ CDOClientProtocol cdoClientProtocol = null;
+ if (sessionProtocol instanceof CDOClientProtocol)
+ {
+ cdoClientProtocol = (CDOClientProtocol)sessionProtocol;
+ }
+ else if (sessionProtocol instanceof DelegatingSessionProtocol)
+ {
+ DelegatingSessionProtocol delegatingSessionProtocol = (DelegatingSessionProtocol)sessionProtocol;
+ CDOSessionProtocol delegate = delegatingSessionProtocol.getDelegate();
+ if (delegate instanceof CDOClientProtocol)
+ {
+ cdoClientProtocol = (CDOClientProtocol)delegate;
+ }
+ }
+ if (cdoClientProtocol != null)
+ {
+ cdoClientProtocol.addListener(this);
+ }
+ }
+
+ public void notifyEvent(IEvent event)
+ {
+ if (event instanceof SignalScheduledEvent)
+ {
+ @SuppressWarnings("unchecked")
+ SignalScheduledEvent<Object> signalScheduledEvent = (SignalScheduledEvent<Object>)event;
+ Signal signal = signalScheduledEvent.getSignal();
+ short signalID = signal.getID();
+ Integer nbRequestCalls = nbRequestsCalls.get(signalID);
+ if (nbRequestCalls == null)
+ {
+ nbRequestCalls = 0;
+ }
+ nbRequestCalls++;
+ nbRequestsCalls.put(signalID, nbRequestCalls);
+ }
+ }
+
+ public Map<Short, Integer> getNBRequestsCalls()
+ {
+ return nbRequestsCalls;
+ }
+
+ }
+
+ /**
+ * A {@link EContentAdapter} to request {@link CDOLockState} on each object of a {@link ResourceSet}.
+ */
+ private static class EContentAdapterQueringCDOLockState extends EContentAdapter
+ {
+
+ @Override
+ protected void addAdapter(Notifier notifier)
+ {
+ if (notifier instanceof EObject)
+ {
+ EObject eObject = (EObject)notifier;
+ CDOObject cdoObject = CDOUtil.getCDOObject(eObject);
+ if (cdoObject != null)
+ {
+ cdoObject.cdoLockState();
+ }
+ }
+
+ super.addAdapter(notifier);
+
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDODefaultLockStateLoadingPolicy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDODefaultLockStateLoadingPolicy.java
new file mode 100644
index 0000000000..eb6efc6f60
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDODefaultLockStateLoadingPolicy.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2004-2014 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.view;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+
+/**
+ * The default {@link CDOLockStateLoadingPolicy lock state loading policy} which ask to load {@link CDOLockState lock state} for each loaded {@link CDORevision revision} with the same number of request to server as for revisions requests.
+ *
+ * @author Esteban Dugueperoux
+ * @since 4.4
+ */
+public class CDODefaultLockStateLoadingPolicy implements CDOLockStateLoadingPolicy
+{
+ public boolean loadLockState(CDOID id)
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLockStateLoadingPolicy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLockStateLoadingPolicy.java
new file mode 100644
index 0000000000..7d95e7602f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOLockStateLoadingPolicy.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2004-2014 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Esteban Dugueperoux - initial API and implementation
+ */
+package org.eclipse.emf.cdo.view;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.view.CDOView.Options;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+/**
+ * An interface to control if {@link CDOLockState lock states} are loaded when {@link CDORevision revisions} are loaded to limit requests sent to server. This interface is to be used when {@link Options#setLockStatePrefetchEnabled(boolean) lock state prefetch view option} is enabled.
+ * <br/>
+ * <br/>
+ * Note that lock states will not be loaded automatically for {@link CDOResource} when being created through {@link ResourceSet#getResource(org.eclipse.emf.common.util.URI, boolean)}, {@link CDOResource#cdoLockState()} must be called explicitly to load it.
+ * @see Options#setLockStatePrefetchEnabled(boolean)
+ * @author Esteban Dugueperoux
+ * @since 4.4
+ */
+public interface CDOLockStateLoadingPolicy
+{
+ /**
+ * Tell if the {@link CDOLockState lock state} must be loaded for the current {@link CDOView view} when the {@link CDORevision revision} corresponding to the specified {@link CDOID id} is loaded.
+ *
+ * @param id the of the loaded revision
+ * @return true to have lock state loaded for the specified revision's id for the current view
+ */
+ boolean loadLockState(CDOID id);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
index ef8eb9eeb3..19311686e5 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
@@ -24,6 +24,7 @@ import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitHistory;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.eresource.CDOBinaryResource;
@@ -618,6 +619,34 @@ IContainer<CDOResourceNode>
public void setInvalidationNotificationEnabled(boolean enabled);
/**
+ * Indicates whether this view will fetch {@link CDOLockState lock states} in its cache when a {@link CDORevision revision} is fetched. A lock state is fetched only if the view's cache does not contains it already or {@link Options#isLockNotificationEnabled()} return false, as in this last case the view's lock state cache can be outdated.
+ *
+ * @see CDOLockState
+ * @since 4.4
+ */
+ public boolean isLockStatePrefetchEnabled();
+
+ /**
+ * Specifies whether this view will load {@link CDOLockState lock states} in its cache when a {@link CDORevision revision} is loaded. A lock state is loaded only if the view's cache does not contains it already or {@link Options#isLockNotificationEnabled() lock notification view option} is disabled, as in this last case the view's lock state cache can be outdated.
+ *
+ * Note that lock state will not be loaded automatically for CDOResource, {@link CDOResource#cdoLockState()} must be called explicitly to load it.
+ *
+ * @see CDOLockState
+ * @since 4.4
+ */
+ public void setLockStatePrefetchEnabled(boolean enabled);
+
+ /**
+ * @since 4.4
+ */
+ public CDOLockStateLoadingPolicy getLockStateLoadingPolicy();
+
+ /**
+ * @since 4.4
+ */
+ public void setLockStateLoadingPolicy(CDOLockStateLoadingPolicy lockStateLoadingPolicy);
+
+ /**
* @since 3.0
*/
public CDOInvalidationPolicy getInvalidationPolicy();
@@ -791,6 +820,19 @@ IContainer<CDOResourceNode>
}
/**
+ * An {@link IOptionsEvent options event} fired from common view {@link CDOCommonView#options() options} when the
+ * {@link Options#setLockStatePrefetchEnabled(boolean) lock state prefetch enabled} option has changed.
+ *
+ * @author Esteban Dugueperoux
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 4.4
+ */
+ public interface LockStatePrefetchEvent extends IOptionsEvent
+ {
+ }
+
+ /**
* An {@link IOptionsEvent options event} fired from view {@link CDOView#options() options} when the
* {@link Options#setInvalidationNotificationEnabled(boolean) invalidation notification enabled} option has changed.
*
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 385ae783e3..65279d0506 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -15,6 +15,7 @@ package org.eclipse.emf.internal.cdo.view;
import org.eclipse.emf.cdo.CDONotification;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -29,6 +30,7 @@ import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.CDORevisionsLoadedEvent;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.common.util.CDOException;
@@ -43,8 +45,10 @@ import org.eclipse.emf.cdo.util.LockTimeoutException;
import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.emf.cdo.util.StaleRevisionLockException;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
+import org.eclipse.emf.cdo.view.CDODefaultLockStateLoadingPolicy;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
+import org.eclipse.emf.cdo.view.CDOLockStateLoadingPolicy;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOView;
@@ -1683,6 +1687,84 @@ public class CDOViewImpl extends AbstractCDOView
}
/**
+ * A {@link IListener} to prefetch {@link CDOLockState lockstates} when {@link CDORevision revisions} are loaded, according to {@link Options#setLockStatePrefetchEnabled(boolean)} option.
+ *
+ * @author Esteban Dugueperoux
+ */
+ private final class LockStatePrefetcher implements IListener
+ {
+ public LockStatePrefetcher()
+ {
+ getSession().getRevisionManager().addListener(this);
+ }
+
+ public void notifyEvent(IEvent event)
+ {
+ if (event instanceof CDORevisionsLoadedEvent)
+ {
+ CDORevisionsLoadedEvent revisionsLoadedEvent = (CDORevisionsLoadedEvent)event;
+ List<CDORevision> loadedRevisions = new ArrayList<CDORevision>();
+ loadedRevisions.addAll(revisionsLoadedEvent.getPrimaryLoadedRevisions());
+ loadedRevisions.addAll(revisionsLoadedEvent.getAdditionalLoadedRevisions());
+
+ Map<CDOID, CDOObject> ids = updateCDOViewObjectsCache(loadedRevisions);
+ if (!ids.isEmpty())
+ {
+ updateCDOViewLockStatesCache(ids.keySet());
+ }
+ }
+ }
+
+ private Map<CDOID, CDOObject> updateCDOViewObjectsCache(List<CDORevision> loadedRevisions)
+ {
+ Map<CDOID, CDOObject> ids = new HashMap<CDOID, CDOObject>();
+ CDOLockStateLoadingPolicy lockStateLoadingPolicy = options().getLockStateLoadingPolicy();
+ for (CDORevision revision : loadedRevisions)
+ {
+ CDOID id = revision.getID();
+ if (id != null && lockStateLoadingPolicy.loadLockState(id))
+ {
+ // - Don't ask to create an object for CDOResource as the caller of ResourceSet.getResource()
+ // can have created it but not yet registered in CDOView.
+ // - Don't ask others CDOResourceNode either as it will create some load revisions request
+ // in addition to mode without lock state prefetch
+ boolean isResourceNode = revision.isResourceNode();
+ InternalCDOObject object = getObject(id, !isResourceNode);
+ if (object != null)
+ {
+ ids.put(id, object);
+ }
+ }
+ }
+
+ return ids;
+ }
+
+ private void updateCDOViewLockStatesCache(Set<CDOID> ids)
+ {
+ CDOLockState[] alreadyLoadedLockStates = getLockStates(ids, false);
+ if (alreadyLoadedLockStates == null || alreadyLoadedLockStates.length < ids.size()
+ || !options().isLockNotificationEnabled())
+ {
+ CDOLockState[] lockStates = getLockStates(ids);
+ updateLockStates(lockStates);
+ for (CDOCommonView view : getSession().getViews())
+ {
+ if (view != CDOViewImpl.this && view.getBranch() == getBranch())
+ {
+ updateLockStates(lockStates);
+ }
+ }
+ }
+ }
+
+ public void dispose()
+ {
+ getSession().getRevisionManager().removeListener(this);
+ }
+ }
+
+ /**
* @author Eike Stepper
*/
private final class InvalidationRunnable implements Runnable
@@ -1817,6 +1899,12 @@ public class CDOViewImpl extends AbstractCDOView
private boolean lockNotificationsEnabled;
+ private boolean lockStatePrefetchEnabled;
+
+ private CDOLockStateLoadingPolicy lockStateLoadingPolicy = new CDODefaultLockStateLoadingPolicy();
+
+ private LockStatePrefetcher lockStatePrefetcher;
+
private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy = CDOUtil
.createRevisionPrefetchingPolicy(NO_REVISION_PREFETCHING);
@@ -1961,6 +2049,56 @@ public class CDOViewImpl extends AbstractCDOView
fireEvent(event);
}
+ public boolean isLockStatePrefetchEnabled()
+ {
+ return lockStatePrefetchEnabled;
+ }
+
+ public void setLockStatePrefetchEnabled(boolean enabled)
+ {
+ checkActive();
+
+ IEvent event = null;
+ synchronized (CDOViewImpl.this)
+ {
+ if (enabled != lockStatePrefetchEnabled)
+ {
+ lockStatePrefetchEnabled = enabled;
+ if (enabled)
+ {
+ lockStatePrefetcher = new LockStatePrefetcher();
+ }
+ else
+ {
+ lockStatePrefetcher.dispose();
+ lockStatePrefetcher = null;
+ }
+
+ event = new LockStatePrefetchEventImpl();
+ }
+ }
+
+ fireEvent(event);
+ }
+
+ public CDOLockStateLoadingPolicy getLockStateLoadingPolicy()
+ {
+ synchronized (CDOViewImpl.this)
+ {
+ return lockStateLoadingPolicy;
+ }
+ }
+
+ public void setLockStateLoadingPolicy(CDOLockStateLoadingPolicy lockStateLoadingPolicy)
+ {
+ checkActive();
+
+ synchronized (CDOViewImpl.this)
+ {
+ this.lockStateLoadingPolicy = lockStateLoadingPolicy;
+ }
+ }
+
public boolean hasChangeSubscriptionPolicies()
{
synchronized (CDOViewImpl.this)
@@ -2295,6 +2433,19 @@ public class CDOViewImpl extends AbstractCDOView
}
/**
+ * @author Esteban Dugueperoux
+ */
+ private final class LockStatePrefetchEventImpl extends OptionsEvent implements LockStatePrefetchEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public LockStatePrefetchEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
+
+ /**
* @author Eike Stepper
*/
private final class RevisionPrefetchingPolicyEventImpl extends OptionsEvent implements

Back to the top