Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Linq / Parallel / Utils / Lookup.cs / 1305376 / Lookup.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// Lookup.cs
//
// [....]
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace System.Linq.Parallel
{
///
/// Lookup class implements the ILookup interface. Lookup is very similar to a dictionary
/// except multiple values are allowed to map to the same key, and null keys are supported.
///
/// Support for null keys adds an issue because the Dictionary class Lookup uses for
/// storage does not support null keys. So, we need to treat null keys separately.
/// Unfortunately, since TKey may be a value type, we cannot test whether the key is null
/// using the user-specified equality comparer.
///
/// C# does allow us to compare the key against null using the == operator, but there is a
/// possibility that the user's equality comparer considers null to be equal to other values.
/// Now, MSDN documentation specifies that if IEqualityComparer.Equals(x,y) returns true, it
/// must be the case that x and y have the same hash code, and null has no hash code. Despite
/// that, we might as well support the use case, even if it is bad practice.
///
/// The solution the Lookup class uses is to treat the key default(TKey) as a special case,
/// and hold its associated grouping - if any - in a special field instead of inserting it
/// into a dictionary.
///
///
///
internal class Lookup : ILookup
{
private IDictionary> m_dict;
private IEqualityComparer m_comparer;
private IGrouping m_defaultKeyGrouping = null;
internal Lookup(IEqualityComparer comparer)
{
m_comparer = comparer;
m_dict = new Dictionary>(m_comparer);
}
public int Count
{
get
{
int count = m_dict.Count;
if (m_defaultKeyGrouping != null)
{
count++;
}
return count;
}
}
// Returns an empty sequence if the key is not in the lookup.
public IEnumerable this[TKey key]
{
get
{
if (m_comparer.Equals(key, default(TKey)))
{
if (m_defaultKeyGrouping != null)
{
return m_defaultKeyGrouping;
}
return Enumerable.Empty();
}
else
{
IGrouping grouping;
if (m_dict.TryGetValue(key, out grouping))
{
return grouping;
}
return Enumerable.Empty();
}
}
}
public bool Contains(TKey key)
{
if (m_comparer.Equals(key, default(TKey)))
{
return m_defaultKeyGrouping != null;
}
else
{
return m_dict.ContainsKey(key);
}
}
//
// Adds a grouping to the lookup
//
// Note: The grouping should be cheap to enumerate (IGrouping extends IEnumerable), as
// it may be enumerated multiple times depending how the user manipulates the lookup.
// Our code must guarantee that we never attempt to insert two groupings with the same
// key into a lookup.
//
internal void Add(IGrouping grouping)
{
if (m_comparer.Equals(grouping.Key, default(TKey)))
{
Contract.Assert(m_defaultKeyGrouping == null, "Cannot insert two groupings with the default key into a lookup.");
m_defaultKeyGrouping = grouping;
}
else
{
Contract.Assert(!m_dict.ContainsKey(grouping.Key));
m_dict.Add(grouping.Key, grouping);
}
}
public IEnumerator> GetEnumerator()
{
// First iterate over the groupings in the dictionary, and then over the default-key
// grouping, if there is one.
foreach (IGrouping grouping in m_dict.Values)
{
yield return grouping;
}
if (m_defaultKeyGrouping != null)
{
yield return m_defaultKeyGrouping;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable>)this).GetEnumerator();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ToolStripDropDownClosingEventArgs.cs
- UnitControl.cs
- XsdValidatingReader.cs
- LocalizationParserHooks.cs
- ThumbAutomationPeer.cs
- ListenDesigner.cs
- SafeNativeMethods.cs
- MatrixTransform3D.cs
- ListViewContainer.cs
- SymbolDocumentInfo.cs
- CurrencyWrapper.cs
- XmlElementList.cs
- XmlSchemaCollection.cs
- filewebrequest.cs
- CompiledRegexRunner.cs
- WarningException.cs
- SystemWebCachingSectionGroup.cs
- InternalUserCancelledException.cs
- InvariantComparer.cs
- PropVariant.cs
- VectorCollectionValueSerializer.cs
- SQLDateTimeStorage.cs
- DataGridViewLayoutData.cs
- AutomationElementIdentifiers.cs
- ListViewDataItem.cs
- SamlSecurityTokenAuthenticator.cs
- BooleanProjectedSlot.cs
- OverrideMode.cs
- ProviderConnectionPoint.cs
- TypeGeneratedEventArgs.cs
- GenerateScriptTypeAttribute.cs
- HttpSessionStateWrapper.cs
- LayoutExceptionEventArgs.cs
- ObjectListCommandsPage.cs
- WebPartDisplayModeCollection.cs
- TextBlockAutomationPeer.cs
- ThreadExceptionDialog.cs
- PackagePartCollection.cs
- OracleParameterCollection.cs
- FieldDescriptor.cs
- WebColorConverter.cs
- GPRECT.cs
- CompilerTypeWithParams.cs
- BaseCollection.cs
- DSASignatureFormatter.cs
- ObjectStateManager.cs
- EventLogRecord.cs
- LabelEditEvent.cs
- XmlComment.cs
- XmlNodeReader.cs
- QueryCreatedEventArgs.cs
- LocatorPartList.cs
- OleDbParameter.cs
- QueryableDataSourceView.cs
- ImageSource.cs
- RightsManagementEncryptedStream.cs
- ProfilePropertyNameValidator.cs
- MethodExpr.cs
- Dump.cs
- TransformerInfoCollection.cs
- KeyGesture.cs
- SchemaLookupTable.cs
- TemplatePagerField.cs
- CultureNotFoundException.cs
- SortedList.cs
- CompilerGlobalScopeAttribute.cs
- OletxEnlistment.cs
- __TransparentProxy.cs
- RunInstallerAttribute.cs
- ConversionContext.cs
- PreProcessInputEventArgs.cs
- MainMenu.cs
- TreeViewDesigner.cs
- ToolStripItemTextRenderEventArgs.cs
- CanonicalXml.cs
- TimelineCollection.cs
- DrawItemEvent.cs
- ControllableStoryboardAction.cs
- GestureRecognitionResult.cs
- UnauthorizedWebPart.cs
- XmlKeywords.cs
- RoleManagerSection.cs
- InertiaExpansionBehavior.cs
- CallbackWrapper.cs
- DLinqDataModelProvider.cs
- Marshal.cs
- UIElementParaClient.cs
- PageCache.cs
- _DynamicWinsockMethods.cs
- CodeTypeReference.cs
- CompatibleIComparer.cs
- SecurityRuntime.cs
- BodyWriter.cs
- StreamUpdate.cs
- ObjectListCommandEventArgs.cs
- ProxyAttribute.cs
- StoryFragments.cs
- ObjectDataSourceFilteringEventArgs.cs
- DiscoveryClientBindingElement.cs
- DependencyPropertyValueSerializer.cs