Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/optimizer/Optimizer.java')
-rw-r--r--plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/optimizer/Optimizer.java328
1 files changed, 328 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/optimizer/Optimizer.java b/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/optimizer/Optimizer.java
new file mode 100644
index 0000000000..4b41d96793
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.lissome/src/org/eclipse/emf/cdo/server/internal/lissome/optimizer/Optimizer.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2004 - 2012 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.server.internal.lissome.optimizer;
+
+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.common.revision.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.CDORevisionCacheAdder;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryResourcesContext;
+import org.eclipse.emf.cdo.server.internal.lissome.LissomeStore;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.concurrent.Worker;
+import org.eclipse.net4j.util.io.IORuntimeException;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.io.IOException;
+import java.util.LinkedList;
+
+/**
+ * @author Eike Stepper
+ */
+public class Optimizer extends Lifecycle
+{
+ private final LissomeStore store;
+
+ private final boolean async;
+
+ private final LinkedList<OptimizerTask> queue = new LinkedList<OptimizerTask>();
+
+ private Worker worker;
+
+ private Cache cache;
+
+ public Optimizer(LissomeStore store, boolean async)
+ {
+ this.store = store;
+ this.async = async;
+ }
+
+ public LissomeStore getStore()
+ {
+ return store;
+ }
+
+ public boolean isAsync()
+ {
+ return async;
+ }
+
+ public OptimizerTask[] getTasks()
+ {
+ return getCache().getTasks();
+ }
+
+ public void addTask(OptimizerTask task)
+ {
+ synchronized (queue)
+ {
+ cache = null;
+ queue.addLast(task);
+ queue.notifyAll();
+ }
+
+ if (!async)
+ {
+ try
+ {
+ executeFirstTask();
+ }
+ catch (InterruptedException ignore)
+ {
+ // Can not happen
+ }
+ }
+ }
+
+ protected void executeFirstTask() throws InterruptedException
+ {
+ try
+ {
+ OptimizerTask task = getFirstTask();
+ task.execute(this);
+ removeFirstTask();
+ }
+ catch (InterruptedException ex)
+ {
+ throw ex;
+ }
+ catch (IOException ex)
+ {
+ throw new IORuntimeException(ex);
+ }
+ }
+
+ protected OptimizerTask getFirstTask() throws InterruptedException
+ {
+ OptimizerTask task;
+ synchronized (queue)
+ {
+ while (queue.isEmpty())
+ {
+ queue.wait(100);
+ }
+
+ task = queue.getFirst();
+ }
+
+ return task;
+ }
+
+ protected void removeFirstTask()
+ {
+ synchronized (queue)
+ {
+ cache = null;
+ queue.removeFirst();
+ queue.notifyAll();
+ }
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+ if (async)
+ {
+ worker = new TaskWorker();
+ worker.activate();
+ }
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ synchronized (queue)
+ {
+ while (!queue.isEmpty())
+ {
+ queue.wait(100);
+ }
+ }
+
+ if (async)
+ {
+ worker.deactivate();
+ worker = null;
+ }
+
+ super.doDeactivate();
+ }
+
+ protected Cache getCache()
+ {
+ synchronized (queue)
+ {
+ if (cache == null)
+ {
+ boolean supportingBranches = store.getRepository().isSupportingBranches();
+ cache = new Cache(queue, supportingBranches);
+ }
+
+ return cache;
+ }
+ }
+
+ public boolean queryResources(IStoreAccessor.QueryResourcesContext context)
+ {
+ Cache cache = getCache();
+ return cache.queryResources(context);
+ }
+
+ public InternalCDORevision readRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ Cache cache = getCache();
+ return cache.readRevision(id, branchPoint);
+ }
+
+ public void handleRevisions(EClass eClass, CDOBranch branch, long timeStamp, boolean exactTime,
+ CDORevisionHandler handler)
+ {
+ // TODO: implement Optimizer.handleRevisions(eClass, branch, timeStamp, exactTime, handler)
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class TaskWorker extends Worker
+ {
+ @Override
+ protected String getThreadName()
+ {
+ return "OptimizerTaskWorker";
+ }
+
+ @Override
+ protected void work(WorkContext context) throws Exception
+ {
+ executeFirstTask();
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class Cache
+ {
+ private final OptimizerTask[] tasks;
+
+ private final boolean supportingBranches;
+
+ private CDORevisionCache revisionCache;
+
+ public Cache(LinkedList<OptimizerTask> queue, boolean supportingBranches)
+ {
+ this.supportingBranches = supportingBranches;
+ tasks = queue.toArray(new OptimizerTask[queue.size()]);
+ }
+
+ public OptimizerTask[] getTasks()
+ {
+ return tasks;
+ }
+
+ public synchronized CDORevisionCache getRevisionCache()
+ {
+ if (revisionCache == null)
+ {
+ revisionCache = CDORevisionUtil.createRevisionCache(true, supportingBranches);
+
+ CDORevisionCacheAdder adder = new CDORevisionCacheAdder()
+ {
+ public void addRevision(CDORevision revision)
+ {
+ reviseOldRevision(revision);
+ revisionCache.addRevision(revision);
+ }
+
+ private void reviseOldRevision(CDORevision revision)
+ {
+ int version = revision.getVersion();
+ if (version > CDOBranchVersion.FIRST_VERSION)
+ {
+ CDOID id = revision.getID();
+ CDOBranchVersion oldVersion = revision.getBranch().getVersion(version - 1);
+ InternalCDORevision oldRevision = (InternalCDORevision)revisionCache.getRevisionByVersion(id, oldVersion);
+ if (oldRevision != null)
+ {
+ oldRevision.setRevised(revision.getTimeStamp() - 1);
+ }
+ }
+ }
+ };
+
+ for (OptimizerTask task : tasks)
+ {
+ if (task instanceof CommitTransactionTask)
+ {
+ CommitTransactionTask commitTask = (CommitTransactionTask)task;
+ commitTask.cacheRevisions(adder);
+ }
+ }
+ }
+
+ return revisionCache;
+ }
+
+ public boolean queryResources(QueryResourcesContext context)
+ {
+ InternalCDORevisionCache revisionCache = (InternalCDORevisionCache)getRevisionCache();
+ for (CDORevision revision : revisionCache.getRevisions(context))
+ {
+ if (!revision.isResourceNode())
+ {
+ continue;
+ }
+
+ CDOID folderID = (CDOID)revision.data().getContainerID();
+ if (!ObjectUtil.equals(folderID, context.getFolderID()))
+ {
+ continue;
+ }
+
+ String name = context.getName();
+ String revisionName = (String)revision.data().get(EresourcePackage.Literals.CDO_RESOURCE_NODE__NAME, 0);
+ boolean useEquals = context.exactMatch() || revisionName == null || name == null;
+ boolean match = useEquals ? ObjectUtil.equals(revisionName, name) : revisionName.startsWith(name);
+ if (!match)
+ {
+ continue;
+ }
+
+ if (!context.addResource(revision.getID()))
+ {
+ // No more results allowed
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public InternalCDORevision readRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ CDORevisionCache revisionCache = getRevisionCache();
+ return (InternalCDORevision)revisionCache.getRevision(id, branchPoint);
+ }
+ }
+}

Back to the top