/*
 * 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);
        }
    }
}
