/*
 * Copyright (c) 2007-2009, 2011-2013, 2015 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.net4j.util.ref;

import java.lang.ref.ReferenceQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * A {@link ConcurrentMap} implementation that uses {@link KeyedReference} instances ({@link KeyedStrongReference},
 * {@link KeyedSoftReference}, {@link KeyedWeakReference} or {@link KeyedPhantomReference}) as its values.
 * <p>
 * A <code>ReferenceValueMap</code> can be used to cache mappings until the <em>value</em> of the mapping is no longer
 * reachable from outside of the map
 * <p>
 * <b>Note:</b> This map is not synchronized. If it is to be used by multiple threads concurrently the user is
 * responsible for applying proper external synchronization!
 *
 * @author Eike Stepper
 */
public abstract class ReferenceValueMap<K, V> extends ReferenceValueMap2<K, V>implements ConcurrentMap<K, V>
{
  public ReferenceValueMap()
  {
    this(new ConcurrentHashMap<K, KeyedReference<K, V>>());
  }

  public ReferenceValueMap(ConcurrentMap<K, KeyedReference<K, V>> map)
  {
    super(map);
  }

  public V putIfAbsent(K key, V value)
  {
    try
    {
      KeyedReference<K, V> ref = createReference(key, value, queue);
      KeyedReference<K, V> oldRef = ((ConcurrentMap<K, KeyedReference<K, V>>)map).putIfAbsent(key, ref);
      return dereference(oldRef);
    }
    finally
    {
      purgeQueue();
    }
  }

  public V replace(K key, V value)
  {
    try
    {
      KeyedReference<K, V> ref = createReference(key, value, queue);
      KeyedReference<K, V> oldRef = ((ConcurrentMap<K, KeyedReference<K, V>>)map).replace(key, ref);
      return dereference(oldRef);
    }
    finally
    {
      purgeQueue();
    }
  }

  public boolean replace(K key, V oldValue, V newValue)
  {
    try
    {
      // TODO Consider a dummy KeyedReference class for oldRef
      KeyedReference<K, V> oldRef = createReference(key, oldValue, queue);
      KeyedReference<K, V> newRef = createReference(key, newValue, queue);
      return ((ConcurrentMap<K, KeyedReference<K, V>>)map).replace(key, oldRef, newRef);
    }
    finally
    {
      purgeQueue();
    }
  }

  public boolean remove(Object key, Object value)
  {
    // TODO Consider a dummy KeyedReference class for value
    return ((ConcurrentMap<K, KeyedReference<K, V>>)map).remove(key, value);
  }

  /**
   * @author Eike Stepper
   */
  public static class Strong<K, V> extends ReferenceValueMap<K, V>
  {
    public Strong()
    {
    }

    public Strong(ConcurrentMap<K, KeyedReference<K, V>> map)
    {
      super(map);
    }

    @Override
    protected KeyedReference<K, V> createReference(K key, V value, ReferenceQueue<V> queue)
    {
      return new KeyedStrongReference<K, V>(key, value);
    }

    @Override
    protected ReferenceQueue<V> createQueue()
    {
      return null;
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class Soft<K, V> extends ReferenceValueMap<K, V>
  {
    public Soft()
    {
    }

    public Soft(ConcurrentMap<K, KeyedReference<K, V>> map)
    {
      super(map);
    }

    @Override
    protected KeyedReference<K, V> createReference(K key, V value, ReferenceQueue<V> queue)
    {
      return new KeyedSoftReference<K, V>(key, value, queue);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class Weak<K, V> extends ReferenceValueMap<K, V>
  {
    public Weak()
    {
    }

    public Weak(ConcurrentMap<K, KeyedReference<K, V>> map)
    {
      super(map);
    }

    @Override
    protected KeyedReference<K, V> createReference(K key, V value, ReferenceQueue<V> queue)
    {
      return new KeyedWeakReference<K, V>(key, value, queue);
    }
  }
}
