CSharp.src.Dfa.ArrayEdgeMap.cs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of antlr4-runtime-testsuite Show documentation
Show all versions of antlr4-runtime-testsuite Show documentation
A collection of tests for ANTLR 4 Runtime libraries.
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Interlocked = System.Threading.Interlocked;
using Volatile = System.Threading.Volatile;
namespace Antlr4.Runtime.Dfa
{
/// Sam Harwell
public sealed class ArrayEdgeMap : AbstractEdgeMap
where T : class
{
private readonly T[] arrayData;
private int size;
public ArrayEdgeMap(int minIndex, int maxIndex)
: base(minIndex, maxIndex)
{
arrayData = new T[maxIndex - minIndex + 1];
}
public override int Count
{
get
{
return Volatile.Read(ref size);
}
}
public override bool IsEmpty
{
get
{
return Count == 0;
}
}
public override bool ContainsKey(int key)
{
return this[key] != null;
}
public override T this[int key]
{
get
{
if (key < minIndex || key > maxIndex)
{
return null;
}
return Volatile.Read(ref arrayData[key - minIndex]);
}
}
public override AbstractEdgeMap Put(int key, T value)
{
if (key >= minIndex && key <= maxIndex)
{
T existing = Interlocked.Exchange(ref arrayData[key - minIndex], value);
if (existing == null && value != null)
{
Interlocked.Increment(ref size);
}
else
{
if (existing != null && value == null)
{
Interlocked.Decrement(ref size);
}
}
}
return this;
}
public override AbstractEdgeMap Remove(int key)
{
return Put(key, null);
}
public override AbstractEdgeMap PutAll(IEdgeMap m)
{
if (m.IsEmpty)
{
return this;
}
if (m is Antlr4.Runtime.Dfa.ArrayEdgeMap)
{
Antlr4.Runtime.Dfa.ArrayEdgeMap other = (Antlr4.Runtime.Dfa.ArrayEdgeMap)m;
int minOverlap = Math.Max(minIndex, other.minIndex);
int maxOverlap = Math.Min(maxIndex, other.maxIndex);
Antlr4.Runtime.Dfa.ArrayEdgeMap result = this;
for (int i = minOverlap; i <= maxOverlap; i++)
{
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap)result.Put(i, m[i]));
}
return result;
}
else
{
if (m is SingletonEdgeMap)
{
SingletonEdgeMap other = (SingletonEdgeMap)m;
System.Diagnostics.Debug.Assert(!other.IsEmpty);
return Put(other.Key, other.Value);
}
else
{
if (m is SparseEdgeMap)
{
SparseEdgeMap other = (SparseEdgeMap)m;
lock (other)
{
int[] keys = other.Keys;
IList values = other.Values;
Antlr4.Runtime.Dfa.ArrayEdgeMap result = this;
for (int i = 0; i < values.Count; i++)
{
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap)result.Put(keys[i], values[i]));
}
return result;
}
}
else
{
throw new NotSupportedException(string.Format("EdgeMap of type {0} is supported yet.", m.GetType().FullName));
}
}
}
}
public override AbstractEdgeMap Clear()
{
return new EmptyEdgeMap(minIndex, maxIndex);
}
public override IReadOnlyDictionary ToMap()
{
if (IsEmpty)
{
return Sharpen.Collections.EmptyMap();
}
IDictionary result = new SortedDictionary();
for (int i = 0; i < arrayData.Length; i++)
{
T element = arrayData[i];
if (element == null)
{
continue;
}
result[i + minIndex] = element;
}
return new ReadOnlyDictionary(result);
}
}
}