blob: 71b442709d5a55ac96755c7b877977d0fd3c945e [file] [log] [blame]
/*
* Copyright (c) 2011, 2012, 2016 Eike Stepper (Loehne, 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:
* Caspar De Groot - initial API and implementation
*/
package org.eclipse.emf.cdo.server.internal.db4o;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockArea.Handler;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockAreaNotFoundException;
import org.eclipse.emf.cdo.common.lock.IDurableLockingManager.LockGrade;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Query;
import java.util.Collection;
import java.util.Map;
/**
* @author Caspar De Groot
*/
public class DB4ODurableLockingManager extends Lifecycle
{
public DB4ODurableLockingManager()
{
}
public LockArea createLockArea(DB4OStoreAccessor accessor, String userID, CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks)
{
String durableLockingID = getNextDurableLockingID(accessor);
LockArea lockArea = CDOLockUtil.createLockArea(durableLockingID, userID, branchPoint, readOnly, locks);
storeLockArea(accessor, lockArea);
return lockArea;
}
private void storeLockArea(DB4OStoreAccessor accessor, LockArea area)
{
ObjectContainer objectContainer = accessor.getObjectContainer();
DB4OLockArea primitiveLockArea = DB4OLockArea.getPrimitiveLockArea(area);
objectContainer.store(primitiveLockArea);
objectContainer.commit();
}
public LockArea getLockArea(DB4OStoreAccessor accessor, String durableLockingID) throws LockAreaNotFoundException
{
DB4OLockArea primitive = getPrimitiveLockArea(accessor, durableLockingID);
return DB4OLockArea.getLockArea(accessor.getStore(), primitive);
}
private DB4OLockArea getPrimitiveLockArea(DB4OStoreAccessor accessor, String durableLockingID) throws LockAreaNotFoundException
{
ObjectContainer container = accessor.getObjectContainer();
Query query = container.query();
query.constrain(DB4OLockArea.class);
query.descend("id").constrain(durableLockingID);
ObjectSet<?> lockAreas = query.execute();
if (lockAreas.isEmpty())
{
throw new LockAreaNotFoundException(durableLockingID);
}
if (lockAreas.size() > 1)
{
throw new AssertionError("Lockarea stored more than once in object database");
}
return (DB4OLockArea)lockAreas.get(0);
}
public void getLockAreas(DB4OStoreAccessor accessor, String userIDPrefix, Handler handler)
{
ObjectContainer container = accessor.getObjectContainer();
Query query = container.query();
query.constrain(DB4OLockArea.class);
if (userIDPrefix.length() > 0)
{
query.descend("userID").constrain(userIDPrefix).startsWith(true);
}
ObjectSet<?> primitives = query.execute();
for (Object primitive : primitives)
{
LockArea area = DB4OLockArea.getLockArea(accessor.getStore(), (DB4OLockArea)primitive);
if (!handler.handleLockArea(area))
{
break;
}
}
}
public void deleteLockArea(DB4OStoreAccessor accessor, String durableLockingID)
{
DB4OLockArea primitive = getPrimitiveLockArea(accessor, durableLockingID);
ObjectContainer container = accessor.getObjectContainer();
container.delete(primitive);
container.commit();
}
public void lock(DB4OStoreAccessor accessor, String durableLockingID, LockType type, Collection<? extends Object> objectsToLock)
{
// TODO (CD) Refactor? Next chunk of code copied verbatim from MEMStore.lock
LockArea area = getLockArea(accessor, durableLockingID);
Map<CDOID, LockGrade> locks = area.getLocks();
InternalLockManager lockManager = accessor.getStore().getRepository().getLockingManager();
for (Object objectToLock : objectsToLock)
{
CDOID id = lockManager.getLockKeyID(objectToLock);
LockGrade grade = locks.get(id);
if (grade != null)
{
grade = grade.getUpdated(type, true);
}
else
{
grade = LockGrade.get(type);
}
locks.put(id, grade);
}
storeLockArea(accessor, area);
}
public void unlock(DB4OStoreAccessor accessor, String durableLockingID, LockType type, Collection<? extends Object> objectsToUnlock)
{
// TODO (CD) Refactor? Next chunk of code copied verbatim from MEMStore.lock
LockArea area = getLockArea(accessor, durableLockingID);
Map<CDOID, LockGrade> locks = area.getLocks();
InternalLockManager lockManager = accessor.getStore().getRepository().getLockingManager();
for (Object objectToUnlock : objectsToUnlock)
{
CDOID id = lockManager.getLockKeyID(objectToUnlock);
LockGrade grade = locks.get(id);
if (grade != null)
{
grade = grade.getUpdated(type, false);
if (grade == LockGrade.NONE)
{
locks.remove(id);
}
else
{
locks.put(id, grade);
}
}
}
storeLockArea(accessor, area);
}
public void unlock(DB4OStoreAccessor accessor, String durableLockingID)
{
LockArea area = getLockArea(accessor, durableLockingID);
Map<CDOID, LockGrade> locks = area.getLocks();
locks.clear();
storeLockArea(accessor, area);
}
// TODO: Refactor -- this was copied verbatim from DurableLockingManager
private String getNextDurableLockingID(DB4OStoreAccessor accessor)
{
for (;;)
{
String durableLockingID = CDOLockUtil.createDurableLockingID();
try
{
getLockArea(accessor, durableLockingID); // Check uniqueness
// Not unique; try once more...
}
catch (LockAreaNotFoundException ex)
{
return durableLockingID;
}
}
}
}