using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

public class AtomDictionary<TKey, TValue>
{
    AtomLock m_Lock = new AtomLock();
    Dictionary<TKey, TValue> m_Dictionary = new Dictionary<TKey, TValue>();
    
    public int Count
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get
        { 
            m_Lock. Lock();
            try
            {
                return m_Dictionary.Count;
            }
            catch (Exception e)
            {
                throw e;
            }

            finally
            {
                m_Lock.UnLock();
            }
        }
    }
 
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Add(TKey key, TValue value)
    {
        m_Lock.Lock();
        try
        {
            m_Dictionary.Add(key, value);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            m_Lock.UnLock();
        }
    }
    
    #if NETCOREAPP
    
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public bool TryAdd(TKey key, TValue value)
    {
        m_Lock.Lock();
        try
        {
            return m_Dictionary.TryAdd(key, value);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            m_Lock.UnLock();
        }
    }

    #endif

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public bool Remove(TKey key)
    {
        m_Lock.Lock();
        try
        {
            return m_Dictionary.Remove(key);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            m_Lock.UnLock();
        }
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public bool TryGetValue(TKey key, out TValue value)
    {
        m_Lock.Lock();
        try
        {
            return m_Dictionary.TryGetValue(key, out value);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            m_Lock.UnLock();
        }
    }

    
    public TValue this[TKey key]
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get
        {
            m_Lock.Lock();
            try
            {
                return m_Dictionary[key];
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                m_Lock.UnLock();
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        set
        {
            m_Lock.Lock();
            try
            { 
                m_Dictionary[key] = value;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                m_Lock.UnLock();
            }
        }
    }
    
    public bool ContainsKey(TKey key)
    {
        m_Lock.Lock();
        try
        {
            return m_Dictionary.ContainsKey(key);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            m_Lock.UnLock();
        }
    }

    public Dictionary<TKey, TValue>.ValueCollection Values
    {
        get
        {
            m_Lock.Lock();
            try
            {
                return m_Dictionary.Values;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                m_Lock.UnLock();
            }
        }
    }

}