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
- AxHostDesigner.cs
- SmtpNtlmAuthenticationModule.cs
- CompiledQuery.cs
- SqlWebEventProvider.cs
- XmlAtomicValue.cs
- CombinedGeometry.cs
- OpenTypeCommon.cs
- XamlDesignerSerializationManager.cs
- SafeMILHandle.cs
- ObjectDataSourceMethodEditor.cs
- UnsafeNativeMethods.cs
- MarkupExtensionParser.cs
- X509ChainElement.cs
- AliasedExpr.cs
- QilDataSource.cs
- PropertyValueChangedEvent.cs
- CredentialSelector.cs
- ResizeGrip.cs
- Exceptions.cs
- QilSortKey.cs
- IPEndPointCollection.cs
- BinaryMessageFormatter.cs
- AsymmetricAlgorithm.cs
- CancelEventArgs.cs
- OracleCommandBuilder.cs
- ExecutionScope.cs
- QuaternionConverter.cs
- SerializationHelper.cs
- WebPartConnectionsConnectVerb.cs
- ZipPackage.cs
- assertwrapper.cs
- LogStore.cs
- DependencyObject.cs
- ExternalCalls.cs
- MemberCollection.cs
- WorkflowMarkupSerializer.cs
- ErrorFormatter.cs
- SafeThreadHandle.cs
- NativeWindow.cs
- OutputScope.cs
- CodeCompileUnit.cs
- ClassicBorderDecorator.cs
- OleStrCAMarshaler.cs
- Emitter.cs
- FreezableDefaultValueFactory.cs
- GridViewSortEventArgs.cs
- ToolStripRenderer.cs
- IsolationInterop.cs
- SchemaDeclBase.cs
- Trustee.cs
- JpegBitmapEncoder.cs
- EntityDataSourceChangedEventArgs.cs
- MSHTMLHost.cs
- TheQuery.cs
- MimeTypeMapper.cs
- BindingMAnagerBase.cs
- KeyGestureConverter.cs
- InputBinding.cs
- AllMembershipCondition.cs
- ResourcePermissionBase.cs
- EntityCollection.cs
- NodeLabelEditEvent.cs
- isolationinterop.cs
- OdbcConnectionStringbuilder.cs
- PropertyInfoSet.cs
- MarkerProperties.cs
- ReverseQueryOperator.cs
- HtmlHead.cs
- PersonalizableTypeEntry.cs
- SafeNativeMethodsOther.cs
- ContentPlaceHolder.cs
- WaveHeader.cs
- AncillaryOps.cs
- ValueType.cs
- ImageAutomationPeer.cs
- XmlDocument.cs
- TimeStampChecker.cs
- BindingGroup.cs
- JapaneseCalendar.cs
- _ProxyChain.cs
- PropertyChangingEventArgs.cs
- AppLevelCompilationSectionCache.cs
- AnchoredBlock.cs
- RefType.cs
- EditorZoneDesigner.cs
- HtmlWindow.cs
- KeyedCollection.cs
- EntitySqlException.cs
- OwnerDrawPropertyBag.cs
- RouteData.cs
- DateTimeValueSerializer.cs
- DataControlLinkButton.cs
- SafeNativeHandle.cs
- TextEffect.cs
- MaterializeFromAtom.cs
- PeerContact.cs
- SrgsGrammarCompiler.cs
- ApplicationContext.cs
- ScrollBar.cs
- WindowsFormsSectionHandler.cs