blob: 168943807769affdbaa360a6d9f1fa462697bd3f [file] [log] [blame]
/*
* Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.identitymaps;
import java.util.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
/**
* Unit of work specific identity map which avoid additional overhead not required in unit of work,
* such as locking and synchronization.
* @author James Sutherland
* @since TopLink 10.1.3.1
*/
public class UnitOfWorkIdentityMap extends FullIdentityMap {
protected UnitOfWorkIdentityMap() {
}
public UnitOfWorkIdentityMap(int size, ClassDescriptor descriptor, AbstractSession session, boolean isolated) {
super();
this.maxSize = size;
// PERF: Use a HashMap as more efficient than a ConcurrentMap and single threaded.
this.cacheKeys = new HashMap(size);
this.descriptor = descriptor;
this.session = session;
this.isIsolated = isolated;
}
@Override
public CacheKey createCacheKey(Object primaryKey, Object object, Object writeLockValue, long readTime) {
return new CacheKey(primaryKey, object, writeLockValue, readTime, true);
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireDeferredLock(Object primaryKey, boolean isCacheCheckComplete) {
CacheKey cacheKey = getCacheKey(primaryKey, false);
if (cacheKey == null) {
CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
cacheKey = putCacheKeyIfAbsent(newCacheKey);
if (cacheKey == null) {
return newCacheKey;
}
}
return cacheKey;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireLock(Object primaryKey, boolean forMerge, boolean isCacheCheckComplete) {
CacheKey cacheKey = getCacheKey(primaryKey, forMerge);
if (cacheKey == null) {
CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
cacheKey = putCacheKeyIfAbsent(newCacheKey);
if (cacheKey == null) {
return newCacheKey;
}
}
return cacheKey;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireLockNoWait(Object primaryKey, boolean forMerge) {
CacheKey cacheKey = getCacheKey(primaryKey, forMerge);
if (cacheKey == null) {
CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
cacheKey = putCacheKeyIfAbsent(newCacheKey);
if (cacheKey == null) {
return newCacheKey;
}
}
return cacheKey;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireLockWithWait(Object primaryKey, boolean forMerge, int wait) {
CacheKey cacheKey = getCacheKey(primaryKey, forMerge);
if (cacheKey == null) {
CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
cacheKey = putCacheKeyIfAbsent(newCacheKey);
if (cacheKey == null) {
return newCacheKey;
}
}
return cacheKey;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireReadLockOnCacheKey(Object primaryKey) {
return acquireReadLockOnCacheKeyNoWait(primaryKey);
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public CacheKey acquireReadLockOnCacheKeyNoWait(Object primaryKey) {
CacheKey newCacheKey = createCacheKey(primaryKey, null, null, 0);
CacheKey cacheKey = getCacheKey(newCacheKey, false);
if (cacheKey == null) {
return newCacheKey;
}
return cacheKey;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
protected CacheKey getCacheKeyWithReadLock(Object primaryKey) {
return getCacheKey(primaryKey, false);
}
/**
* Use hashmap put, as no concurrency in unit of work.
*/
@Override
protected CacheKey putCacheKeyIfAbsent(CacheKey searchKey) {
searchKey.setOwningMap(this);
this.cacheKeys.put(searchKey.getKey(), searchKey);
return null;
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public Object remove(CacheKey cacheKey) {
if (cacheKey != null) {
this.cacheKeys.remove(cacheKey.getKey());
cacheKey.setOwningMap(null);
} else {
return null;
}
return cacheKey.getObject();
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public void resetCacheKey(CacheKey key, Object object, Object writeLockValue, long readTime) {
key.setObject(object);
key.setWriteLockValue(writeLockValue);
key.setReadTime(readTime);
}
/**
* Avoid acquiring any lock as uow is single threaded.
*/
@Override
public void setWriteLockValue(Object primaryKey, Object writeLockValue) {
CacheKey cacheKey = getCacheKeyForLock(primaryKey);
if (cacheKey != null) {
cacheKey.setWriteLockValue(writeLockValue);
}
}
}