using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
#pragma warning disable 0420
public partial class LockFreeDictionary<K, V> : IDictionary<K, V>
where K : IEquatable<K>
where V : IEquatable<V>
{
public partial class Config
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public partial class EntryBlock
{
public EntryBlock(Config cfg, int block_no)
{
this.cfg = cfg;
this.i_block = block_no;
this.rg = new Entry[cfg.EntriesPerBlock];
}
readonly Config cfg;
readonly Entry[] rg;
internal EntryBlock next = null;
internal void StoreEntryHot(int offs, ref Entry e)
{
Thread.MemoryBarrier();
rg[offs] = e;
}
internal void SetEntryNext(int offs, int gx_next)
{
rg[offs].gx_next = gx_next; /// C# volatile
}
internal void SetFreelistNext(int offs, int gx_next)
{
rg[offs].gx_next = gx_next; /// C# volatile
rg[offs].hash = Entry.FreelistHash;
}
internal void SetEntryHash(int offs, uint h)
{
rg[offs].hash = h; /// C# volatile
}
internal int TransactEntryNext(int offs, int gx_next, int gx_compare)
{
return Interlocked.CompareExchange(ref rg[offs].gx_next, gx_next, gx_compare);
}
internal int GetNextHot(int offs)
{
return rg[offs].gx_next; /// C# volatile
}
internal uint GetHashAndNextHot(int offs, out int gx_next)
{
gx_next = rg[offs].gx_next; /// C# volatile
return rg[offs].hash; /// C# volatile
}
internal void GetEntryHot(int offs, out Entry e)
{
e = rg[offs];
Thread.MemoryBarrier();
}
internal void GetKeyHot(int offs, out K key)
{
key = rg[offs].key;
Thread.MemoryBarrier();
}
internal void GetValueHot(int offs, out V value)
{
value = rg[offs].value;
Thread.MemoryBarrier();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public partial struct Entry
{
#if DEBUG
static internal Entry AllocDefault = new Entry(-1, 0, default(K), default(V));
static internal Entry FreelistDefault = new Entry(0, 0, default(K), default(V));
#endif
internal const int FreelistHash = 0;
/// to merit 'beforefieldinit' semantics, we eschew doing all of the following in a static constructor
static readonly Type t_key = typeof(K);
static readonly Type t_value = typeof(V);
static internal readonly bool f_value_type_key = t_key.IsValueType;
static internal readonly bool f_value_type_value = t_value.IsValueType;
static internal readonly bool f_key_null_check = !f_value_type_key || Nullable.GetUnderlyingType(t_key) != null;
static internal int StructureSize { get { return cb_ent; } }
static readonly int cb_ent = sizeof(int) + sizeof(uint) +
(f_value_type_key ? Marshal.SizeOf(default(K)) : IntPtr.Size) +
(f_value_type_value ? Marshal.SizeOf(default(V)) : IntPtr.Size);
internal Entry(int gx_next, uint hash, K key, V value)
{
this.gx_next = gx_next;
this.hash = hash;
this.key = key;
this.value = value;
}
internal Entry(uint hash, K key, V value)
: this(-1, hash, key, value)
{
}
volatile internal int gx_next;
volatile internal uint hash;
readonly internal K key;
readonly internal V value;
static internal bool CompareValues(V v1, V v2)
{
return (!f_value_type_value && v1 == null) ? v2 == null : v1.Equals(v2);
}
};
};
};
};