public override int IndexOf(string parameterName)
{
NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "IndexOf", parameterName);
int retIndex;
int scanIndex;
if ((parameterName[0] == ':') || (parameterName[0] == '@'))
{
parameterName = parameterName.Remove(0, 1);
}
// Using a dictionary is much faster for 5 or more items
if (this.InternalList.Count >= 5)
{
if (this.lookup == null)
{
this.lookup = new Dictionary<string, int>();
for (scanIndex = 0 ; scanIndex < this.InternalList.Count ; scanIndex++)
{
var item = this.InternalList[scanIndex];
// Store only the first of each distinct value
if (! this.lookup.ContainsKey(item.CleanName))
{
this.lookup.Add(item.CleanName, scanIndex);
}
}
}
// Try to access the case sensitive parameter name first
if (this.lookup.TryGetValue(parameterName, out retIndex))
{
return retIndex;
}
// Case sensitive lookup failed, generate a case insensitive lookup
if (this.lookupIgnoreCase == null)
{
this.lookupIgnoreCase = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
for (scanIndex = 0 ; scanIndex < this.InternalList.Count ; scanIndex++)
{
var item = this.InternalList[scanIndex];
// Store only the first of each distinct value
if (! this.lookupIgnoreCase.ContainsKey(item.CleanName))
{
this.lookupIgnoreCase.Add(item.CleanName, scanIndex);
}
}
}
// Then try to access the case insensitive parameter name
if (this.lookupIgnoreCase.TryGetValue(parameterName, out retIndex))
{
return retIndex;
}
return -1;
}
retIndex = -1;
// Scan until a case insensitive match is found, and save its index for possible return.
// Items that don't match loosely cannot possibly match exactly.
for (scanIndex = 0 ; scanIndex < this.InternalList.Count ; scanIndex++)
{
var item = this.InternalList[scanIndex];
if (string.Compare(parameterName, item.CleanName, StringComparison.InvariantCultureIgnoreCase) == 0)
{
retIndex = scanIndex;
break;
}
}
// Then continue the scan until a case sensitive match is found, and return it.
// If a case insensitive match was found, it will be re-checked for an exact match.
for ( ; scanIndex < this.InternalList.Count ; scanIndex++)
{
var item = this.InternalList[scanIndex];
if(item.CleanName == parameterName)
{
return scanIndex;
}
}
// If a case insensitive match was found, it will be returned here.
return retIndex;
}