Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / QueryUtil.cs / 1 / QueryUtil.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; #if NO internal interface IQueryBufferPool { // Clear all pools void Reset(); // Trim pools void Trim(); } #endif // // Generic struct representing ranges within buffers // internal struct QueryRange { internal int end; // INCLUSIVE - the end of the range internal int start; // INCLUSIVE - the start of the range #if NO internal QueryRange(int offset, QueryRange range) { this.start = range.start + offset; this.end = range.end + offset; } #endif internal QueryRange(int start, int end) { this.start = start; this.end = end; } internal int Count { get { return this.end - this.start + 1; } } #if NO internal int this[int offset] { get { return this.start + offset; } } internal bool IsNotEmpty { get { return (this.end >= this.start); } } internal void Clear() { this.end = this.start - 1; } internal void Grow(int offset) { this.end += offset; } #endif internal bool IsInRange(int point) { return (this.start <= point && point <= this.end); } #if NO internal void Set(int start, int end) { this.start = start; this.end = end; } #endif internal void Shift(int offset) { this.start += offset; this.end += offset; } } ////// Our own buffer management /// There are a few reasons why we don't reuse something in System.Collections.Generic /// 1. We want Clear() to NOT reallocate the internal array. We want it to simply set the Count = 0 /// This allows us to reuse buffers with impunity. /// 2. We want to be able to replace the internal buffer in a collection with a different one. Again, /// this is to help with pooling /// 3. We want to be able to control how fast buffers grow. /// 4. Does absolutely no bounds or null checking. As fast as we can make it. All checking should be done /// by whoever wraps this. Checking is unnecessary for many internal uses where we need optimal perf. /// 5. Does more precise trimming /// 6. AND this is a struct /// /// internal struct QueryBuffer{ internal T[] buffer; // buffer of T. Frequently larger than count internal int count; // Actual # of items internal static T[] EmptyBuffer = new T[0]; /// /// Construct a new buffer /// /// internal QueryBuffer(int capacity) { if (0 == capacity) { this.buffer = QueryBuffer.EmptyBuffer; } else { this.buffer = new T[capacity]; } this.count = 0; } #if NO internal QueryBuffer(QueryBuffer buffer) { this.buffer = (T[]) buffer.buffer.Clone(); this.count = buffer.count; } internal QueryBuffer(T[] buffer) { DiagnosticUtility.DebugAssert(null != buffer, ""); this.buffer = buffer; this.count = 0; } /// /// Get and set the internal buffer /// If you set the buffer, the count will automatically be set to 0 /// internal T[] Buffer { get { return this.buffer; } set { DiagnosticUtility.DebugAssert(null != value, ""); this.buffer = value; this.count = 0; } } #endif ////// # of items /// internal int Count { get { return this.count; } #if NO set { DiagnosticUtility.DebugAssert(value >= 0 && value <= this.buffer.Length, ""); this.count = value; } #endif } #if NO ////// How much can it hold /// internal int Capacity { get { return this.buffer.Length; } set { DiagnosticUtility.DebugAssert(value >= this.count, ""); if (value > this.buffer.Length) { Array.Resize(ref this.buffer, value); } } } #endif internal T this[int index] { get { return this.buffer[index]; } set { this.buffer[index] = value; } } #if NO internal void Add() { if (this.count == this.buffer.Length) { Array.Resize (ref this.buffer, this.count > 0 ? this.count * 2 : 16); } this.count++; } #endif /// /// Add an element to the buffer /// internal void Add(T t) { if (this.count == this.buffer.Length) { Array.Resize(ref this.buffer, this.count > 0 ? this.count * 2 : 16); } this.buffer[this.count++] = t; } #if NO /// /// Useful when this is a buffer of structs /// internal void AddReference(ref T t) { if (this.count == this.buffer.Length) { Array.Resize(ref this.buffer, this.count > 0 ? this.count * 2 : 16); } this.buffer[this.count++] = t; } #endif /// /// Add all the elements in the given buffer to this one /// We can do this very efficiently using an Array Copy /// internal void Add(ref QueryBufferaddBuffer) { if (1 == addBuffer.count) { this.Add(addBuffer.buffer[0]); return; } int newCount = this.count + addBuffer.count; if (newCount >= this.buffer.Length) { this.Grow(newCount); } // Copy all the new elements in Array.Copy(addBuffer.buffer, 0, this.buffer, this.count, addBuffer.count); this.count = newCount; } #if NO internal void Add(T[] addBuffer, int startAt, int addCount) { int newCount = this.count + addCount; if (newCount >= this.buffer.Length) { this.Grow(newCount); } // Copy all the new elements in Array.Copy(addBuffer, startAt, this.buffer, this.count, addCount); this.count = newCount; } /// /// Add without attempting to grow the buffer. Faster, but must be used with care. /// Caller must ensure that the buffer is large enough. /// internal void AddOnly(T t) { this.buffer[this.count++] = t; } #endif ////// Set the count to zero but do NOT get rid of the actual buffer /// internal void Clear() { this.count = 0; } #if NO // // Copy from one location in the buffer to another // internal void Copy(int from, int to) { this.buffer[to] = this.buffer[from]; } internal void Copy(int from, int to, int count) { Array.Copy(this.buffer, from, this.buffer, to, count); } #endif internal void CopyFrom(ref QueryBufferaddBuffer) { int addCount = addBuffer.count; switch (addCount) { default: if (addCount > this.buffer.Length) { this.buffer = new T[addCount]; } // Copy all the new elements in Array.Copy(addBuffer.buffer, 0, this.buffer, 0, addCount); this.count = addCount; break; case 0: this.count = 0; break; case 1: if (this.buffer.Length == 0) { this.buffer = new T[1]; } this.buffer[0] = addBuffer.buffer[0]; this.count = 1; break; } } #if NO /// /// Ensure that the internal buffer has adequate capacity /// internal void EnsureCapacity(int capacity) { if (capacity > this.buffer.Length) { this.Grow(capacity); } } internal void Erase() { Array.Clear(this.buffer, 0, this.count); this.count = 0; } #endif void Grow(int capacity) { int newCapacity = this.buffer.Length * 2; Array.Resize(ref this.buffer, capacity > newCapacity ? capacity : newCapacity); } internal int IndexOf(T t) { for (int i = 0; i < this.count; ++i) { if (t.Equals(this.buffer[i])) { return i; } } return -1; } internal int IndexOf(T t, int startAt) { for (int i = startAt; i < this.count; ++i) { if (t.Equals(this.buffer[i])) { return i; } } return -1; } #if NO internal void InsertAt(T t, int at) { this.ReserveAt(at, 1); this.buffer[at] = t; } #endif internal bool IsValidIndex(int index) { return (index >= 0 && index < this.count); } #if NO internal T Pop() { DiagnosticUtility.DebugAssert(this.count > 0, ""); return this.buffer[--this.count]; } internal void Push(T t) { this.Add(t); } #endif /// /// Reserve enough space for count elements /// internal void Reserve(int reserveCount) { int newCount = this.count + reserveCount; if (newCount >= this.buffer.Length) { this.Grow(newCount); } this.count = newCount; } internal void ReserveAt(int index, int reserveCount) { if (index == this.count) { this.Reserve(reserveCount); return; } int newCount; if (index > this.count) { // We want to reserve starting at a location past what is current committed. // No shifting needed newCount = index + reserveCount + 1; if (newCount >= this.buffer.Length) { this.Grow(newCount); } } else { // reserving space within an already allocated portion of the buffer // we'll ensure that the buffer can fit 'newCount' items, then shift by reserveCount starting at index newCount = this.count + reserveCount; if (newCount >= this.buffer.Length) { this.Grow(newCount); } // Move to make room Array.Copy(this.buffer, index, this.buffer, index + reserveCount, this.count - index); } this.count = newCount; } internal void Remove(T t) { int index = this.IndexOf(t); if (index >= 0) { this.RemoveAt(index); } } internal void RemoveAt(int index) { if (index < this.count - 1) { Array.Copy(this.buffer, index + 1, this.buffer, index, this.count - index - 1); } this.count--; } internal void Sort(IComparercomparer) { Array.Sort (this.buffer, 0, this.count, comparer); } #if NO /// /// Reduce the buffer capacity so that it is no greater than twice the element count /// internal void Trim() { int maxSize = this.count * 2; if (maxSize < this.buffer.Length / 2) { if (0 == maxSize) { this.buffer = QueryBuffer.EmptyBuffer; } else { T[] newBuffer = new T[maxSize]; Array.Copy(this.buffer, newBuffer, maxSize); } } } #endif /// /// Reduce the buffer capacity so that its size is exactly == to the element count /// internal void TrimToCount() { if (this.count < this.buffer.Length) { if (0 == this.count) { this.buffer = QueryBuffer.EmptyBuffer; } else { T[] newBuffer = new T[this.count]; Array.Copy(this.buffer, newBuffer, this.count); } } } } internal struct SortedBuffer where C : IComparer , new() { int size; T[] buffer; static readonly DefaultComparer Comparer = new DefaultComparer(); internal T this[int index] { get { return GetAt(index); } } internal int Capacity { #if NO get { return this.buffer == null ? 0 : this.buffer.Length; } #endif set { if (this.buffer != null) { if (value != this.buffer.Length) { DiagnosticUtility.DebugAssert(value >= this.size, "New capacity must be >= size"); if (value > 0) { Array.Resize(ref this.buffer, value); } else { this.buffer = null; } } } else { this.buffer = new T[value]; } } } internal int Count { get { return this.size; } } internal int Add(T item) { int i = Search(item); if (i < 0) { i = ~i; InsertAt(i, item); } return i; } #if NO internal void CopyTo(T[] array) { CopyTo(array, 0, this.size); } internal void CopyTo(T[] array, int start, int length) { DiagnosticUtility.DebugAssert(array != null, ""); DiagnosticUtility.DebugAssert(start >= 0, ""); DiagnosticUtility.DebugAssert(length >= 0, ""); DiagnosticUtility.DebugAssert(start + length < this.size, ""); Array.Copy(this.buffer, 0, array, start, length); } #endif internal void Clear() { this.size = 0; } #if NO internal bool Contains(T item) { return IndexOf(item) >= 0; } #endif internal void Exchange(T old, T replace) { if (Comparer.Compare(old, replace) == 0) { int i = IndexOf(old); if (i >= 0) { this.buffer[i] = replace; } else { Insert(replace); } } else { // PERF, [....], can this be made more efficient? Does it need to be? Remove(old); Insert(replace); } } internal T GetAt(int index) { DiagnosticUtility.DebugAssert(index < this.size, "Index is greater than size"); return this.buffer[index]; } internal int IndexOf(T item) { return Search(item); } internal int IndexOfKey (K key, IItemComparer itemComp) { return Search(key, itemComp); } internal int Insert(T item) { int i = Search(item); if (i >= 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new ArgumentException(SR.GetString(SR.QueryItemAlreadyExists))); } // If an item is not found, Search returns the bitwise negation of // the index an item should inserted at; InsertAt(~i, item); return ~i; } void InsertAt(int index, T item) { DiagnosticUtility.DebugAssert(index >= 0 && index <= this.size, ""); if (this.buffer == null) { this.buffer = new T[1]; } else if (this.buffer.Length == this.size) { // PERF, [....], how should we choose a new size? T[] tmp = new T[this.size + 1]; if (index == 0) { Array.Copy(this.buffer, 0, tmp, 1, this.size); } else if (index == this.size) { Array.Copy(this.buffer, 0, tmp, 0, this.size); } else { Array.Copy(this.buffer, 0, tmp, 0, index); Array.Copy(this.buffer, index, tmp, index + 1, this.size - index); } this.buffer = tmp; } else { Array.Copy(this.buffer, index, this.buffer, index + 1, this.size - index); } this.buffer[index] = item; ++this.size; } internal bool Remove(T item) { int i = IndexOf(item); if (i >= 0) { RemoveAt(i); return true; } return false; } internal void RemoveAt(int index) { DiagnosticUtility.DebugAssert(index >= 0 && index < this.size, ""); if (index < this.size - 1) { Array.Copy(this.buffer, index + 1, this.buffer, index, this.size - index - 1); } this.buffer[--this.size] = default(T); } int Search(T item) { if (size == 0) return ~0; return Search(item, Comparer); } int Search (K key, IItemComparer comparer) { if (this.size <= 8) { return LinearSearch (key, comparer, 0, this.size); } else { return BinarySearch(key, comparer); } } int BinarySearch (K key, IItemComparer comparer) { // [low, high) int low = 0; int high = this.size; int mid, result; // Binary search is implemented here so we could look for a type that is different from the // buffer type. Also, the search switches to linear for 8 or fewer elements. while (high - low > 8) { mid = (high + low) / 2; result = comparer.Compare(key, this.buffer[mid]); if (result < 0) { high = mid; } else if (result > 0) { low = mid + 1; } else { return mid; } } return LinearSearch (key, comparer, low, high); } // [start, bound) int LinearSearch (K key, IItemComparer comparer, int start, int bound) { int result; for (int i = start; i < bound; ++i) { result = comparer.Compare(key, this.buffer[i]); if (result == 0) { return i; } if (result < 0) { // Return the bitwise negation of the insertion index return ~i; } } // Return the bitwise negation of the insertion index return ~bound; } #if NO internal T[] ToArray() { T[] tmp = new T[this.size]; Array.Copy(this.buffer, 0, tmp, 0, this.size); return tmp; } #endif internal void Trim() { this.Capacity = this.size; } internal class DefaultComparer : IItemComparer { public static readonly IComparer Comparer = new C(); public int Compare(T item1, T item2) { return Comparer.Compare(item1, item2); } } } internal interface IItemComparer { int Compare(K key, V value); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CultureInfo.cs
- SignedInfo.cs
- TextDataBindingHandler.cs
- RefreshPropertiesAttribute.cs
- ListSurrogate.cs
- CachedPathData.cs
- Blend.cs
- TitleStyle.cs
- RSACryptoServiceProvider.cs
- shaperfactory.cs
- TraceListener.cs
- Label.cs
- OverrideMode.cs
- AudioDeviceOut.cs
- GridViewDeletedEventArgs.cs
- EdmProperty.cs
- Permission.cs
- bidPrivateBase.cs
- Root.cs
- SqlDataAdapter.cs
- ParamArrayAttribute.cs
- GeneralTransform3D.cs
- ObjectViewListener.cs
- TemplatedControlDesigner.cs
- WebSysDescriptionAttribute.cs
- StylesEditorDialog.cs
- WindowsFormsHostPropertyMap.cs
- BulletedListEventArgs.cs
- DispatcherFrame.cs
- ProcessRequestArgs.cs
- securestring.cs
- DataGridBoolColumn.cs
- Peer.cs
- StrongNamePublicKeyBlob.cs
- Native.cs
- DependencyPropertyKind.cs
- AlternationConverter.cs
- UIElementHelper.cs
- XmlComment.cs
- ServiceXNameTypeConverter.cs
- SymLanguageVendor.cs
- DataKeyArray.cs
- SafeFileMappingHandle.cs
- RegisteredArrayDeclaration.cs
- PrefixHandle.cs
- HeaderedItemsControl.cs
- TypedServiceChannelBuilder.cs
- XamlRtfConverter.cs
- HttpUnhandledOperationInvoker.cs
- AddressingVersion.cs
- Point3DAnimationBase.cs
- StyleSelector.cs
- BaseParser.cs
- RestHandlerFactory.cs
- RemoteHelper.cs
- QueryFunctions.cs
- MailWriter.cs
- JsonEnumDataContract.cs
- WhitespaceRuleReader.cs
- EncoderFallback.cs
- AnnotationMap.cs
- DataBindingCollection.cs
- UriSection.cs
- ArraySegment.cs
- ContextBase.cs
- WorkflowMarkupSerializationException.cs
- OdbcErrorCollection.cs
- DataGridColumnHeadersPresenter.cs
- ToolStripDropDownClosedEventArgs.cs
- ArgumentException.cs
- SqlError.cs
- SecurityDocument.cs
- AssertUtility.cs
- SqlBinder.cs
- ProfileSettingsCollection.cs
- DBCSCodePageEncoding.cs
- _HeaderInfoTable.cs
- MetadataArtifactLoaderCompositeResource.cs
- panel.cs
- KeyTime.cs
- FacetEnabledSchemaElement.cs
- PeerNameRegistration.cs
- ParsedAttributeCollection.cs
- SimpleHandlerFactory.cs
- SqlMethodCallConverter.cs
- PrincipalPermissionMode.cs
- Compilation.cs
- SecurityElement.cs
- PolyQuadraticBezierSegment.cs
- ImageSource.cs
- MsmqIntegrationAppDomainProtocolHandler.cs
- UserControlAutomationPeer.cs
- ParserExtension.cs
- DesignerActionGlyph.cs
- DES.cs
- SimpleModelProvider.cs
- TemplateField.cs
- RelativeSource.cs
- DateTimeSerializationSection.cs
- DrawingImage.cs