private static HashEntry GetHashEntry(Type enumType)
{
HashEntry hashEntry = (HashEntry)fieldInfoHash[enumType];
if (hashEntry == null)
{
// To reduce the workingset we clear the hashtable when a threshold number of elements are inserted.
if (fieldInfoHash.Count > maxHashElements)
fieldInfoHash.Clear();
ulong[] values = null;
String[] names = null;
BCLDebug.Assert(enumType.BaseType == typeof(Enum), "Base type must of type Enum");
if (enumType.BaseType == typeof(Enum))
InternalGetEnumValues(enumType, ref values, ref names);
// If we switch over to EnumBuilder, this code path will be required.
else
{
// fall back on reflection for odd cases
FieldInfo[] flds = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
values = new ulong[flds.Length];
names = new String[flds.Length];
for (int i = 0; i < flds.Length; i++)
{
names[i] = flds[i].Name;
values[i] = ToUInt64(flds[i].GetValue(null));
}
// Insertion Sort these values in ascending order.
// We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
// the common case performance will be faster than quick sorting this.
for (int i = 1; i < values.Length; i++)
{
int j = i;
String tempStr = names[i];
ulong val = values[i];
bool exchanged = false;
// Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
while (values[j - 1] > val)
{
names[j] = names[j - 1];
values[j] = values[j - 1];
j--;
exchanged = true;
if (j == 0)
break;
}
if (exchanged)
{
names[j] = tempStr;
values[j] = val;
}
}
}
hashEntry = new HashEntry(names, values);
fieldInfoHash[enumType] = hashEntry;
}
return hashEntry;
}