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
- WebPartChrome.cs
- File.cs
- SessionStateModule.cs
- CodeMemberProperty.cs
- assertwrapper.cs
- ApplyHostConfigurationBehavior.cs
- PersonalizationProviderHelper.cs
- Drawing.cs
- NTAccount.cs
- MaskedTextProvider.cs
- WebRequestModulesSection.cs
- XmlBindingWorker.cs
- TransformValueSerializer.cs
- NativeMethods.cs
- TemplatedMailWebEventProvider.cs
- WebPartHeaderCloseVerb.cs
- BooleanSwitch.cs
- XomlCompilerHelpers.cs
- RealizationContext.cs
- DataContractSerializerOperationFormatter.cs
- StateChangeEvent.cs
- FontStretchConverter.cs
- StaticExtensionConverter.cs
- XmlTextWriter.cs
- MaskedTextProvider.cs
- ISAPIRuntime.cs
- Rect3D.cs
- ControlUtil.cs
- MetadataException.cs
- ObjectView.cs
- PriorityQueue.cs
- DataTableTypeConverter.cs
- ProfileService.cs
- ToolStripGripRenderEventArgs.cs
- DataPagerFieldItem.cs
- NativeMethodsOther.cs
- CollectionAdapters.cs
- Quaternion.cs
- Decimal.cs
- RoleManagerSection.cs
- OdbcParameterCollection.cs
- WindowsGraphics.cs
- EntityAdapter.cs
- DataGridViewBand.cs
- InkPresenterAutomationPeer.cs
- ConnectionsZoneAutoFormat.cs
- TouchPoint.cs
- X509Utils.cs
- IncrementalReadDecoders.cs
- XsltLibrary.cs
- RoleBoolean.cs
- PublisherIdentityPermission.cs
- TraceUtils.cs
- InteropBitmapSource.cs
- HMACMD5.cs
- VirtualPathProvider.cs
- ECDsa.cs
- ProtectedUri.cs
- AvtEvent.cs
- _SslState.cs
- SqlProfileProvider.cs
- EncryptedPackageFilter.cs
- X509Extension.cs
- XmlNavigatorFilter.cs
- GiveFeedbackEvent.cs
- NamespaceExpr.cs
- TdsParserStaticMethods.cs
- Main.cs
- GeometryValueSerializer.cs
- RuntimeHandles.cs
- JapaneseLunisolarCalendar.cs
- TrackingRecord.cs
- Collection.cs
- IisTraceWebEventProvider.cs
- ThreadAbortException.cs
- Stylesheet.cs
- ServicePointManagerElement.cs
- StrokeRenderer.cs
- ListViewCommandEventArgs.cs
- InputLanguageProfileNotifySink.cs
- ClientTargetCollection.cs
- AssignDesigner.xaml.cs
- MailFileEditor.cs
- TreeView.cs
- SubMenuStyleCollectionEditor.cs
- RelationshipDetailsRow.cs
- SetterBaseCollection.cs
- Group.cs
- Msec.cs
- MethodAccessException.cs
- KeyNotFoundException.cs
- DataRowChangeEvent.cs
- InstanceHandle.cs
- SystemNetworkInterface.cs
- DispatcherOperation.cs
- ByteViewer.cs
- ResourceDescriptionAttribute.cs
- ClientScriptManagerWrapper.cs
- HwndAppCommandInputProvider.cs
- XmlILStorageConverter.cs