diff options
author | Eike Stepper | 2011-05-12 06:48:33 +0000 |
---|---|---|
committer | Eike Stepper | 2011-05-12 06:48:33 +0000 |
commit | 19d9d396bd36434f526dabf460c4c58b5e7bb656 (patch) | |
tree | 44b3539a8ffe256890d1011bd1e991adf0e130e4 /plugins/org.eclipse.emf.cdo.common/src | |
parent | 6e57c26f8ff08ca0de456784f857b06810691f23 (diff) | |
download | cdo-19d9d396bd36434f526dabf460c4c58b5e7bb656.tar.gz cdo-19d9d396bd36434f526dabf460c4c58b5e7bb656.tar.xz cdo-19d9d396bd36434f526dabf460c4c58b5e7bb656.zip |
[345049] Optimize CDORevisionCache implementations
https://bugs.eclipse.org/bugs/show_bug.cgi?id=345049
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src')
8 files changed, 647 insertions, 194 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java index 08a1a6d9d9..3e38871bd2 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java @@ -25,7 +25,9 @@ import org.eclipse.emf.cdo.internal.common.commit.CDOChangeSetImpl; import org.eclipse.emf.cdo.internal.common.messages.Messages; import org.eclipse.emf.cdo.internal.common.revision.CDOFeatureMapEntryImpl; import org.eclipse.emf.cdo.internal.common.revision.CDORevisableImpl; -import org.eclipse.emf.cdo.internal.common.revision.CDORevisionCacheImpl; +import org.eclipse.emf.cdo.internal.common.revision.CDORevisionCacheAuditing; +import org.eclipse.emf.cdo.internal.common.revision.CDORevisionCacheBranching; +import org.eclipse.emf.cdo.internal.common.revision.CDORevisionCacheNonAuditing; import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl; import org.eclipse.emf.cdo.internal.common.revision.CDORevisionKeyImpl; import org.eclipse.emf.cdo.internal.common.revision.CDORevisionManagerImpl; @@ -61,13 +63,23 @@ public final class CDORevisionUtil } /** - * Creates and returns a new memory sensitive revision cache that supports branches. + * Creates and returns a new memory sensitive revision cache. * * @since 4.0 */ - public static CDORevisionCache createRevisionCache() + public static CDORevisionCache createRevisionCache(boolean supportingAudits, boolean supportingBranches) { - return new CDORevisionCacheImpl(); + if (supportingBranches) + { + return new CDORevisionCacheBranching(); + } + + if (supportingAudits) + { + return new CDORevisionCacheAuditing(); + } + + return new CDORevisionCacheNonAuditing(); } /** diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/AbstractCDORevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/AbstractCDORevisionCache.java new file mode 100644 index 0000000000..df0689cbef --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/AbstractCDORevisionCache.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2004 - 2011 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 + * Simon McDuff - bug 201266 + * Simon McDuff - bug 230832 + */ +package org.eclipse.emf.cdo.internal.common.revision; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionKey; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache; + +import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.ref.ReferenceQueueWorker; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.text.MessageFormat; + +/** + * @author Eike Stepper + */ +public abstract class AbstractCDORevisionCache extends ReferenceQueueWorker<InternalCDORevision> implements + InternalCDORevisionCache +{ + private static boolean disableGC; + + public AbstractCDORevisionCache() + { + } + + @Override + protected void work(Reference<? extends InternalCDORevision> reference) + { + CDORevisionKey key = (CDORevisionKey)reference; + + CDOID id = key.getID(); + CDOBranch branch = key.getBranch(); + int version = key.getVersion(); + + InternalCDORevision revision = (InternalCDORevision)removeRevision(id, branch.getVersion(version)); + if (revision == null) + { + // Use revision in eviction event + key = revision; + } + + IListener[] listeners = getListeners(); + if (listeners != null) + { + fireEvent(new EvictionEventImpl(this, key), listeners); + } + } + + protected Reference<InternalCDORevision> createReference(CDORevision revision) + { + if (disableGC) + { + return new CacheStrongReference((InternalCDORevision)revision); + } + + return new CacheSoftReference((InternalCDORevision)revision, getQueue()); + } + + /** + * @author Eike Stepper + */ + private static final class CacheSoftReference extends SoftReference<InternalCDORevision> implements CDORevisionKey + { + private CDOID id; + + private CDOBranch branch; + + private int version; + + public CacheSoftReference(InternalCDORevision revision, ReferenceQueue<InternalCDORevision> queue) + { + super(revision, queue); + id = revision.getID(); + branch = revision.getBranch(); + version = revision.getVersion(); + } + + public CDOID getID() + { + return id; + } + + public CDOBranch getBranch() + { + return branch; + } + + public int getVersion() + { + return version; + } + + @Override + public String toString() + { + return MessageFormat.format("{0}:{1}v{2}", getID(), getBranch().getID(), getVersion()); + } + } + + /** + * @author Eike Stepper + */ + private static final class CacheStrongReference extends SoftReference<InternalCDORevision> implements CDORevisionKey + { + private CDOID id; + + private CDOBranch branch; + + private int version; + + public CacheStrongReference(InternalCDORevision revision) + { + super(revision); + id = revision.getID(); + branch = revision.getBranch(); + version = revision.getVersion(); + } + + public CDOID getID() + { + return id; + } + + public CDOBranch getBranch() + { + return branch; + } + + public int getVersion() + { + return version; + } + + @Override + public String toString() + { + return MessageFormat.format("{0}:{1}v{2}", getID(), getBranch().getID(), getVersion()); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheAuditing.java index fd1b5255ac..839added0a 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheAuditing.java @@ -16,8 +16,6 @@ import org.eclipse.emf.cdo.common.branch.CDOBranch; 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.emf.cdo.common.id.CDOIDUtil; -import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionKey; import org.eclipse.emf.cdo.internal.common.bundle.OM; @@ -25,18 +23,11 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache; import org.eclipse.net4j.util.CheckUtil; -import org.eclipse.net4j.util.ObjectUtil; -import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.om.trace.ContextTracer; -import org.eclipse.net4j.util.ref.KeyedReference; -import org.eclipse.net4j.util.ref.KeyedSoftReference; -import org.eclipse.net4j.util.ref.KeyedStrongReference; -import org.eclipse.net4j.util.ref.ReferenceQueueWorker; import org.eclipse.emf.ecore.EClass; import java.lang.ref.Reference; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -48,33 +39,34 @@ import java.util.Map; /** * @author Eike Stepper */ -public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevision> implements InternalCDORevisionCache +public class CDORevisionCacheAuditing extends AbstractCDORevisionCache { - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionCacheImpl.class); + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionCacheAuditing.class); - private static boolean disableGC; + protected Map<Object, RevisionList> revisionLists = new HashMap<Object, RevisionList>(); - private Map<CDOIDAndBranch, RevisionList> revisionLists = new HashMap<CDOIDAndBranch, RevisionList>(); - - private Map<CDOID, TypeAndRefCounter> typeMap = new HashMap<CDOID, TypeAndRefCounter>(); - - public CDORevisionCacheImpl() + public CDORevisionCacheAuditing() { } public InternalCDORevisionCache instantiate(CDORevision revision) { - return new CDORevisionCacheImpl(); + return new CDORevisionCacheAuditing(); } public EClass getObjectType(CDOID id) { synchronized (revisionLists) { - TypeAndRefCounter typeCounter = typeMap.get(id); - if (typeCounter != null) + RevisionList revisionList = revisionLists.get(id); + if (revisionList != null) { - return typeCounter.getType(); + Reference<InternalCDORevision> ref = revisionList.getFirst(); + InternalCDORevision revision = ref.get(); + if (revision != null) + { + return revision.getEClass(); + } } return null; @@ -121,12 +113,50 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi return currentRevisions; } + public Map<CDOBranch, List<CDORevision>> getAllRevisions() + { + Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>(); + synchronized (revisionLists) + { + for (RevisionList list : revisionLists.values()) + { + list.getAllRevisions(result); + } + } + + return result; + } + + public List<CDORevision> getRevisions(CDOBranchPoint branchPoint) + { + List<CDORevision> result = new ArrayList<CDORevision>(); + CDOBranch branch = branchPoint.getBranch(); + synchronized (revisionLists) + { + for (Map.Entry<Object, RevisionList> entry : revisionLists.entrySet()) + { + if (isKeyInBranch(entry.getKey(), branch)) + // if (ObjectUtil.equals(entry.getKey().getBranch(), branch)) + { + RevisionList list = entry.getValue(); + InternalCDORevision revision = list.getRevision(branchPoint.getTimeStamp()); + if (revision != null) + { + result.add(revision); + } + } + } + } + + return result; + } + public void addRevision(CDORevision revision) { CheckUtil.checkArg(revision, "revision"); CDOID id = revision.getID(); - CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(id, revision.getBranch()); + Object key = createKey(id, revision.getBranch()); synchronized (revisionLists) { @@ -137,23 +167,14 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi revisionLists.put(key, list); } - InternalCDORevision rev = (InternalCDORevision)revision; - list.addRevision(rev, createReference(key, rev)); - - TypeAndRefCounter typeCounter = typeMap.get(id); - if (typeCounter == null) - { - typeCounter = new TypeAndRefCounter(revision.getEClass()); - typeMap.put(id, typeCounter); - } - - typeCounter.increase(); + list.addRevision((InternalCDORevision)revision, createReference(revision)); + typeRefIncrease(id, revision.getEClass()); } } public InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion) { - CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(id, branchVersion.getBranch()); + Object key = createKey(id, branchVersion.getBranch()); synchronized (revisionLists) { RevisionList list = revisionLists.get(key); @@ -163,12 +184,7 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi if (list.isEmpty()) { revisionLists.remove(key); - - TypeAndRefCounter typeCounter = typeMap.get(id); - if (typeCounter != null && typeCounter.decreaseAndGet() == 0) - { - typeMap.remove(id); - } + typeRefDecrease(id); if (TRACER.isEnabled()) { @@ -186,7 +202,7 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi synchronized (revisionLists) { revisionLists.clear(); - typeMap.clear(); + typeRefDispose(); } } @@ -199,130 +215,44 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi } } - public Map<CDOBranch, List<CDORevision>> getAllRevisions() + protected void typeRefIncrease(CDOID id, EClass type) { - Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>(); - synchronized (revisionLists) - { - for (RevisionList list : revisionLists.values()) - { - list.getAllRevisions(result); - } - } - - return result; + // Do nothing } - public List<CDORevision> getRevisions(CDOBranchPoint branchPoint) + protected void typeRefDecrease(CDOID id) { - List<CDORevision> result = new ArrayList<CDORevision>(); - CDOBranch branch = branchPoint.getBranch(); - synchronized (revisionLists) - { - for (Map.Entry<CDOIDAndBranch, RevisionList> entry : revisionLists.entrySet()) - { - if (ObjectUtil.equals(entry.getKey().getBranch(), branch)) - { - RevisionList list = entry.getValue(); - InternalCDORevision revision = list.getRevision(branchPoint.getTimeStamp()); - if (revision != null) - { - result.add(revision); - } - } - } - } - - return result; + // Do nothing } - @Override - protected void work(Reference<? extends InternalCDORevision> reference) + protected void typeRefDispose() { - @SuppressWarnings("unchecked") - KeyedReference<CDORevisionKey, InternalCDORevision> keyedRef = (KeyedReference<CDORevisionKey, InternalCDORevision>)reference; - CDORevisionKey key = keyedRef.getKey(); - - CDOID id = key.getID(); - CDOBranch branch = key.getBranch(); - int version = key.getVersion(); - - InternalCDORevision revision = removeRevision(id, branch.getVersion(version)); - if (revision == null) - { - // Use revision in eviction event - key = revision; - } - - IListener[] listeners = getListeners(); - if (listeners != null) - { - fireEvent(new EvictionEventImpl(this, key), listeners); - } + // Do nothing } - private KeyedReference<CDORevisionKey, InternalCDORevision> createReference(CDOIDAndBranch idAndBranch, - InternalCDORevision revision) + protected Object createKey(CDOID id, CDOBranch branch) { - CDORevisionKey key = new RevisionKey(idAndBranch, revision.getVersion()); - if (disableGC) - { - return new KeyedStrongReference<CDORevisionKey, InternalCDORevision>(key, revision); - } - - return new KeyedSoftReference<CDORevisionKey, InternalCDORevision>(key, revision, getQueue()); + return id; } - private RevisionList getRevisionList(CDOID id, CDOBranch branch) + protected boolean isKeyInBranch(Object key, CDOBranch branch) { - CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(id, branch); - synchronized (revisionLists) - { - return revisionLists.get(key); - } + return true; } - /** - * @author Eike Stepper - */ - private static final class RevisionKey implements CDORevisionKey + protected RevisionList getRevisionList(CDOID id, CDOBranch branch) { - private CDOIDAndBranch idAndBranch; - - private int version; - - public RevisionKey(CDOIDAndBranch idAndBranch, int version) - { - this.idAndBranch = idAndBranch; - this.version = version; - } - - public CDOID getID() - { - return idAndBranch.getID(); - } - - public CDOBranch getBranch() - { - return idAndBranch.getBranch(); - } - - public int getVersion() - { - return version; - } - - @Override - public String toString() + Object key = createKey(id, branch); + synchronized (revisionLists) { - return MessageFormat.format("{0}:{1}v{2}", getID(), getBranch().getID(), getVersion()); + return revisionLists.get(key); } } /** * @author Eike Stepper */ - private static final class RevisionList extends LinkedList<KeyedReference<CDORevisionKey, InternalCDORevision>> + protected static final class RevisionList extends LinkedList<Reference<InternalCDORevision>> { private static final long serialVersionUID = 1L; @@ -334,7 +264,7 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi { if (timeStamp == CDORevision.UNSPECIFIED_DATE) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = isEmpty() ? null : getFirst(); + Reference<InternalCDORevision> ref = isEmpty() ? null : getFirst(); if (ref != null) { InternalCDORevision revision = ref.get(); @@ -354,9 +284,9 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi return null; } - for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();) + for (Iterator<Reference<InternalCDORevision>> it = iterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); + Reference<InternalCDORevision> ref = it.next(); InternalCDORevision revision = ref.get(); if (revision != null) { @@ -383,9 +313,9 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi public synchronized InternalCDORevision getRevisionByVersion(int version) { - for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();) + for (Iterator<Reference<InternalCDORevision>> it = iterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); + Reference<InternalCDORevision> ref = it.next(); InternalCDORevision revision = ref.get(); if (revision != null) { @@ -408,17 +338,16 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi return null; } - public synchronized boolean addRevision(InternalCDORevision revision, - KeyedReference<CDORevisionKey, InternalCDORevision> reference) + public synchronized boolean addRevision(InternalCDORevision revision, Reference<InternalCDORevision> reference) { int version = revision.getVersion(); - for (ListIterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = listIterator(); it.hasNext();) + for (ListIterator<Reference<InternalCDORevision>> it = listIterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); + Reference<InternalCDORevision> ref = it.next(); InternalCDORevision foundRevision = ref.get(); if (foundRevision != null) { - CDORevisionKey key = ref.getKey(); + CDORevisionKey key = (CDORevisionKey)ref; int v = key.getVersion(); if (v == version) { @@ -444,10 +373,10 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi public synchronized void removeRevision(int version) { - for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();) + for (Iterator<Reference<InternalCDORevision>> it = iterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); - CDORevisionKey key = ref.getKey(); + Reference<InternalCDORevision> ref = it.next(); + CDORevisionKey key = (CDORevisionKey)ref; int v = key.getVersion(); if (v == version) { @@ -470,9 +399,9 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi public String toString() { StringBuffer buffer = new StringBuffer(); - for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();) + for (Iterator<Reference<InternalCDORevision>> it = iterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); + Reference<InternalCDORevision> ref = it.next(); InternalCDORevision revision = ref.get(); if (buffer.length() == 0) { @@ -492,9 +421,9 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi public void getAllRevisions(Map<CDOBranch, List<CDORevision>> result) { - for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();) + for (Iterator<Reference<InternalCDORevision>> it = iterator(); it.hasNext();) { - KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next(); + Reference<InternalCDORevision> ref = it.next(); InternalCDORevision revision = ref.get(); if (revision != null) { @@ -511,34 +440,4 @@ public class CDORevisionCacheImpl extends ReferenceQueueWorker<InternalCDORevisi } } } - - /** - * @author Eike Stepper - */ - private static final class TypeAndRefCounter - { - private EClass type; - - private int refCounter; - - public TypeAndRefCounter(EClass type) - { - this.type = type; - } - - public EClass getType() - { - return type; - } - - public void increase() - { - ++refCounter; - } - - public int decreaseAndGet() - { - return --refCounter; - } - } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheBranching.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheBranching.java new file mode 100644 index 0000000000..c64f373d15 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheBranching.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2004 - 2011 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 + * Simon McDuff - bug 201266 + * Simon McDuff - bug 230832 + */ +package org.eclipse.emf.cdo.internal.common.revision; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache; + +import org.eclipse.net4j.util.ObjectUtil; + +import org.eclipse.emf.ecore.EClass; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public class CDORevisionCacheBranching extends CDORevisionCacheAuditing +{ + private Map<CDOID, TypeAndRefCounter> typeMap = new HashMap<CDOID, TypeAndRefCounter>(); + + public CDORevisionCacheBranching() + { + } + + @Override + public InternalCDORevisionCache instantiate(CDORevision revision) + { + return new CDORevisionCacheBranching(); + } + + @Override + public EClass getObjectType(CDOID id) + { + synchronized (revisionLists) + { + TypeAndRefCounter typeCounter = typeMap.get(id); + if (typeCounter != null) + { + return typeCounter.getType(); + } + + return null; + } + } + + @Override + protected void typeRefIncrease(CDOID id, EClass type) + { + TypeAndRefCounter typeCounter = typeMap.get(id); + if (typeCounter == null) + { + typeCounter = new TypeAndRefCounter(type); + typeMap.put(id, typeCounter); + } + + typeCounter.increase(); + } + + @Override + protected void typeRefDecrease(CDOID id) + { + TypeAndRefCounter typeCounter = typeMap.get(id); + if (typeCounter != null && typeCounter.decreaseAndGet() == 0) + { + typeMap.remove(id); + } + } + + @Override + protected void typeRefDispose() + { + typeMap.clear(); + } + + @Override + protected boolean isKeyInBranch(Object key, CDOBranch branch) + { + return ObjectUtil.equals(((CDOIDAndBranch)key).getBranch(), branch); + } + + @Override + protected Object createKey(CDOID id, CDOBranch branch) + { + return CDOIDUtil.createIDAndBranch(id, branch); + } + + /** + * @author Eike Stepper + */ + private static final class TypeAndRefCounter + { + private EClass type; + + private int refCounter; + + public TypeAndRefCounter(EClass type) + { + this.type = type; + } + + public EClass getType() + { + return type; + } + + public void increase() + { + ++refCounter; + } + + public int decreaseAndGet() + { + return --refCounter; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheNonAuditing.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheNonAuditing.java new file mode 100644 index 0000000000..44bdce9c64 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionCacheNonAuditing.java @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2004 - 2011 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 + * Simon McDuff - bug 201266 + * Simon McDuff - bug 230832 + */ +package org.eclipse.emf.cdo.internal.common.revision; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +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.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache; + +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ObjectUtil; + +import org.eclipse.emf.ecore.EClass; + +import java.lang.ref.Reference; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public class CDORevisionCacheNonAuditing extends AbstractCDORevisionCache +{ + private Map<CDOID, Reference<InternalCDORevision>> revisions = new HashMap<CDOID, Reference<InternalCDORevision>>(); + + public CDORevisionCacheNonAuditing() + { + } + + public InternalCDORevisionCache instantiate(CDORevision revision) + { + return new CDORevisionCacheNonAuditing(); + } + + public EClass getObjectType(CDOID id) + { + synchronized (revisions) + { + Reference<InternalCDORevision> ref = revisions.get(id); + if (ref != null) + { + InternalCDORevision revision = ref.get(); + if (revision != null) + { + return revision.getEClass(); + } + } + + return null; + } + } + + public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint) + { + synchronized (revisions) + { + Reference<InternalCDORevision> ref = revisions.get(id); + if (ref != null) + { + InternalCDORevision revision = ref.get(); + if (revision != null && revision.isValid(branchPoint)) + { + return revision; + } + } + + return null; + } + } + + public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion) + { + synchronized (revisions) + { + Reference<InternalCDORevision> ref = revisions.get(id); + if (ref != null) + { + InternalCDORevision revision = ref.get(); + if (revision != null && revision.getVersion() == branchVersion.getVersion()) + { + return revision; + } + } + + return null; + } + } + + public List<CDORevision> getCurrentRevisions() + { + List<CDORevision> currentRevisions = new ArrayList<CDORevision>(); + synchronized (revisions) + { + for (Reference<InternalCDORevision> ref : revisions.values()) + { + InternalCDORevision revision = ref.get(); + if (revision != null && !revision.isHistorical()) + { + currentRevisions.add(revision); + } + } + } + + return currentRevisions; + } + + public Map<CDOBranch, List<CDORevision>> getAllRevisions() + { + Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>(); + synchronized (revisions) + { + List<CDORevision> list = new ArrayList<CDORevision>(); + for (Reference<InternalCDORevision> ref : revisions.values()) + { + InternalCDORevision revision = ref.get(); + if (revision != null) + { + list.add(revision); + } + } + + if (!list.isEmpty()) + { + result.put(list.get(0).getBranch(), list); + } + } + + return result; + } + + public List<CDORevision> getRevisions(CDOBranchPoint branchPoint) + { + List<CDORevision> result = new ArrayList<CDORevision>(); + synchronized (revisions) + { + for (Reference<InternalCDORevision> ref : revisions.values()) + { + InternalCDORevision revision = ref.get(); + if (revision != null && revision.isValid(branchPoint)) + { + result.add(revision); + } + } + } + + return result; + } + + public void addRevision(CDORevision revision) + { + CheckUtil.checkArg(revision, "revision"); + if (!revision.isHistorical()) + { + synchronized (revisions) + { + revisions.put(revision.getID(), createReference(revision)); + } + } + } + + public InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion) + { + synchronized (revisions) + { + Reference<InternalCDORevision> ref = revisions.get(id); + if (ref != null) + { + InternalCDORevision revision = ref.get(); + if (revision != null && ObjectUtil.equals(revision.getBranch(), branchVersion.getBranch()) + && revision.getVersion() == branchVersion.getVersion()) + { + revisions.remove(id); + return revision; + } + } + else + { + revisions.remove(id); + } + } + + return null; + } + + public void clear() + { + synchronized (revisions) + { + revisions.clear(); + } + } + + @Override + public String toString() + { + synchronized (revisions) + { + return revisions.toString(); + } + } +} 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 d27681509e..9600474611 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 @@ -49,6 +49,8 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionManagerImpl.class); + private boolean supportingAudits; + private boolean supportingBranches; private RevisionLoader revisionLoader; @@ -83,6 +85,17 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi { } + public boolean isSupportingAudits() + { + return supportingAudits; + } + + public void setSupportingAudits(boolean on) + { + checkInactive(); + supportingAudits = on; + } + public boolean isSupportingBranches() { return supportingBranches; @@ -420,7 +433,7 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi if (cache == null) { - cache = (InternalCDORevisionCache)CDORevisionUtil.createRevisionCache(); + cache = (InternalCDORevisionCache)CDORevisionUtil.createRevisionCache(supportingAudits, supportingBranches); } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java index 58d1c7b34c..045818a4f4 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java @@ -77,6 +77,22 @@ public abstract class DelegatingCDORevisionManager extends Lifecycle implements getDelegate().setRevisionLocker(revisionLocker); } + /** + * @since 4.0 + */ + public boolean isSupportingAudits() + { + return getDelegate().isSupportingAudits(); + } + + /** + * @since 4.0 + */ + public void setSupportingAudits(boolean on) + { + getDelegate().setSupportingAudits(on); + } + public boolean isSupportingBranches() { return getDelegate().isSupportingBranches(); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java index b20d3ced75..556d46b851 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java @@ -30,6 +30,16 @@ import java.util.List; */ public interface InternalCDORevisionManager extends CDORevisionManager, CDORevisionCacheAdder, ILifecycle { + /** + * @since 4.0 + */ + public boolean isSupportingAudits(); + + /** + * @since 4.0 + */ + public void setSupportingAudits(boolean on); + public boolean isSupportingBranches(); public void setSupportingBranches(boolean on); |