Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Data / System / Data / RecordManager.cs / 5 / RecordManager.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Collections.Generic; using System.Diagnostics; internal sealed class RecordManager { private readonly DataTable table; private int lastFreeRecord; private int minimumCapacity = 50; private int recordCapacity = 0; private readonly ListfreeRecordList = new List (); DataRow[] rows; internal RecordManager(DataTable table) { if (table == null) { throw ExceptionBuilder.ArgumentNull("table"); } this.table = table; } private void GrowRecordCapacity() { if (NewCapacity(recordCapacity) < NormalizedMinimumCapacity(minimumCapacity)) RecordCapacity = NormalizedMinimumCapacity(minimumCapacity); else RecordCapacity = NewCapacity(recordCapacity); // set up internal map : record --> row DataRow[] newRows = table.NewRowArray(recordCapacity); if (rows != null) { Array.Copy(rows, 0, newRows, 0, Math.Min(lastFreeRecord, rows.Length)); } rows = newRows; } internal int LastFreeRecord { get { return lastFreeRecord; } } internal int MinimumCapacity { get { return minimumCapacity; } set { if (minimumCapacity != value) { if (value < 0) { throw ExceptionBuilder.NegativeMinimumCapacity(); } minimumCapacity = value; } } } internal int RecordCapacity { get { return recordCapacity; } set { if (recordCapacity != value) { for (int i = 0; i < table.Columns.Count; i++) { table.Columns[i].SetCapacity(value); } recordCapacity = value; } } } internal static int NewCapacity(int capacity) { return (capacity < 128) ? 128 : (capacity + capacity); } // Normalization: 64, 256, 1024, 2k, 3k, .... private int NormalizedMinimumCapacity(int capacity) { if (capacity < 1024 - 10) { if (capacity < 256 - 10) { if ( capacity < 54 ) return 64; return 256; } return 1024; } return (((capacity + 10) >> 10) + 1) << 10; } internal int NewRecordBase() { int record; if (freeRecordList.Count != 0) { record = freeRecordList[freeRecordList.Count - 1]; freeRecordList.RemoveAt(freeRecordList.Count - 1); } else { if (lastFreeRecord >= recordCapacity) { GrowRecordCapacity(); } record = lastFreeRecord; lastFreeRecord++; } Debug.Assert(record >=0 && record < recordCapacity, "NewRecord: Invalid record"); return record; } internal void FreeRecord(ref int record) { Debug.Assert(-1 <= record && record < recordCapacity, "invalid record"); // Debug.Assert(record < lastFreeRecord, "Attempt to Free() record"); if (-1 != record) { this[record] = null; int count = table.columnCollection.Count; for(int i = 0; i < count; ++i) { table.columnCollection[i].FreeRecord(record); } // if freeing the last record, recycle it if (lastFreeRecord == record + 1) { lastFreeRecord--; } else if (record < lastFreeRecord) { // Debug.Assert(-1 == freeRecordList.IndexOf(record), "Attempt to double Free() record"); freeRecordList.Add(record); } record = -1; } } internal void Clear(bool clearAll) { if (clearAll) { for(int record = 0; record < recordCapacity; ++record) { rows[record] = null; } int count = table.columnCollection.Count; for(int i = 0; i < count; ++i) { // SQLBU 415729: Serious performance issue when calling Clear() // this improves performance by caching the column instead of obtaining it for each row DataColumn column = table.columnCollection[i]; for(int record = 0; record < recordCapacity; ++record) { column.FreeRecord(record); } } lastFreeRecord = 0; freeRecordList.Clear(); } else { // just clear attached rows freeRecordList.Capacity = freeRecordList.Count + table.Rows.Count; for(int record = 0; record < recordCapacity; ++record) { if (rows[record]!= null && rows[record].rowID != -1) { int tempRecord = record; FreeRecord(ref tempRecord); } } } } internal DataRow this[int record] { get { Debug.Assert(record >= 0 && record < rows.Length, "Invalid record number"); return rows[record]; } set { Debug.Assert(record >= 0 && record < rows.Length, "Invalid record number"); rows[record] = value; } } internal void SetKeyValues(int record, DataKey key, object[] keyValues) { for (int i = 0; i < keyValues.Length; i++) { key.ColumnsReference[i][record] = keyValues[i]; } } // Increases AutoIncrementCurrent internal int ImportRecord(DataTable src, int record) { return CopyRecord(src, record, -1); } // No impact on AutoIncrementCurrent if over written internal int CopyRecord(DataTable src, int record, int copy) { Debug.Assert(src != null, "Can not Merge record without a table"); if (record == -1) { return copy; } int newRecord = -1; try { if (copy == -1) { newRecord = table.NewUninitializedRecord(); } else { newRecord = copy; } int count = table.Columns.Count; for (int i = 0; i < count; ++i) { DataColumn dstColumn = table.Columns[i]; DataColumn srcColumn = src.Columns[dstColumn.ColumnName]; if (null != srcColumn) { object value = srcColumn[record]; ICloneable cloneableObject = value as ICloneable; if (null != cloneableObject) { dstColumn[newRecord] = cloneableObject.Clone(); } else { dstColumn[newRecord] = value; } } else if (-1 == copy) { dstColumn.Init(newRecord); } } } catch (Exception e){ // if (Common.ADP.IsCatchableOrSecurityExceptionType(e)) { if (-1 == copy) { FreeRecord(ref newRecord); } } throw; } return newRecord; } internal void SetRowCache(DataRow[] newRows) { rows = newRows; lastFreeRecord = rows.Length; recordCapacity = lastFreeRecord; } [Conditional("DEBUG")] internal void VerifyRecord(int record) { Debug.Assert((record < lastFreeRecord) && (-1 == freeRecordList.IndexOf(record)), "accesing free record"); Debug.Assert((null == rows[record]) || (record == rows[record].oldRecord) || (record == rows[record].newRecord) || (record == rows[record].tempRecord), "record of a different row"); } [Conditional("DEBUG")] internal void VerifyRecord(int record, DataRow row) { Debug.Assert((record < lastFreeRecord) && (-1 == freeRecordList.IndexOf(record)), "accesing free record"); Debug.Assert((null == rows[record]) || (row == rows[record]), "record of a different row"); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Collections.Generic; using System.Diagnostics; internal sealed class RecordManager { private readonly DataTable table; private int lastFreeRecord; private int minimumCapacity = 50; private int recordCapacity = 0; private readonly ListfreeRecordList = new List (); DataRow[] rows; internal RecordManager(DataTable table) { if (table == null) { throw ExceptionBuilder.ArgumentNull("table"); } this.table = table; } private void GrowRecordCapacity() { if (NewCapacity(recordCapacity) < NormalizedMinimumCapacity(minimumCapacity)) RecordCapacity = NormalizedMinimumCapacity(minimumCapacity); else RecordCapacity = NewCapacity(recordCapacity); // set up internal map : record --> row DataRow[] newRows = table.NewRowArray(recordCapacity); if (rows != null) { Array.Copy(rows, 0, newRows, 0, Math.Min(lastFreeRecord, rows.Length)); } rows = newRows; } internal int LastFreeRecord { get { return lastFreeRecord; } } internal int MinimumCapacity { get { return minimumCapacity; } set { if (minimumCapacity != value) { if (value < 0) { throw ExceptionBuilder.NegativeMinimumCapacity(); } minimumCapacity = value; } } } internal int RecordCapacity { get { return recordCapacity; } set { if (recordCapacity != value) { for (int i = 0; i < table.Columns.Count; i++) { table.Columns[i].SetCapacity(value); } recordCapacity = value; } } } internal static int NewCapacity(int capacity) { return (capacity < 128) ? 128 : (capacity + capacity); } // Normalization: 64, 256, 1024, 2k, 3k, .... private int NormalizedMinimumCapacity(int capacity) { if (capacity < 1024 - 10) { if (capacity < 256 - 10) { if ( capacity < 54 ) return 64; return 256; } return 1024; } return (((capacity + 10) >> 10) + 1) << 10; } internal int NewRecordBase() { int record; if (freeRecordList.Count != 0) { record = freeRecordList[freeRecordList.Count - 1]; freeRecordList.RemoveAt(freeRecordList.Count - 1); } else { if (lastFreeRecord >= recordCapacity) { GrowRecordCapacity(); } record = lastFreeRecord; lastFreeRecord++; } Debug.Assert(record >=0 && record < recordCapacity, "NewRecord: Invalid record"); return record; } internal void FreeRecord(ref int record) { Debug.Assert(-1 <= record && record < recordCapacity, "invalid record"); // Debug.Assert(record < lastFreeRecord, "Attempt to Free() record"); if (-1 != record) { this[record] = null; int count = table.columnCollection.Count; for(int i = 0; i < count; ++i) { table.columnCollection[i].FreeRecord(record); } // if freeing the last record, recycle it if (lastFreeRecord == record + 1) { lastFreeRecord--; } else if (record < lastFreeRecord) { // Debug.Assert(-1 == freeRecordList.IndexOf(record), "Attempt to double Free() record"); freeRecordList.Add(record); } record = -1; } } internal void Clear(bool clearAll) { if (clearAll) { for(int record = 0; record < recordCapacity; ++record) { rows[record] = null; } int count = table.columnCollection.Count; for(int i = 0; i < count; ++i) { // SQLBU 415729: Serious performance issue when calling Clear() // this improves performance by caching the column instead of obtaining it for each row DataColumn column = table.columnCollection[i]; for(int record = 0; record < recordCapacity; ++record) { column.FreeRecord(record); } } lastFreeRecord = 0; freeRecordList.Clear(); } else { // just clear attached rows freeRecordList.Capacity = freeRecordList.Count + table.Rows.Count; for(int record = 0; record < recordCapacity; ++record) { if (rows[record]!= null && rows[record].rowID != -1) { int tempRecord = record; FreeRecord(ref tempRecord); } } } } internal DataRow this[int record] { get { Debug.Assert(record >= 0 && record < rows.Length, "Invalid record number"); return rows[record]; } set { Debug.Assert(record >= 0 && record < rows.Length, "Invalid record number"); rows[record] = value; } } internal void SetKeyValues(int record, DataKey key, object[] keyValues) { for (int i = 0; i < keyValues.Length; i++) { key.ColumnsReference[i][record] = keyValues[i]; } } // Increases AutoIncrementCurrent internal int ImportRecord(DataTable src, int record) { return CopyRecord(src, record, -1); } // No impact on AutoIncrementCurrent if over written internal int CopyRecord(DataTable src, int record, int copy) { Debug.Assert(src != null, "Can not Merge record without a table"); if (record == -1) { return copy; } int newRecord = -1; try { if (copy == -1) { newRecord = table.NewUninitializedRecord(); } else { newRecord = copy; } int count = table.Columns.Count; for (int i = 0; i < count; ++i) { DataColumn dstColumn = table.Columns[i]; DataColumn srcColumn = src.Columns[dstColumn.ColumnName]; if (null != srcColumn) { object value = srcColumn[record]; ICloneable cloneableObject = value as ICloneable; if (null != cloneableObject) { dstColumn[newRecord] = cloneableObject.Clone(); } else { dstColumn[newRecord] = value; } } else if (-1 == copy) { dstColumn.Init(newRecord); } } } catch (Exception e){ // if (Common.ADP.IsCatchableOrSecurityExceptionType(e)) { if (-1 == copy) { FreeRecord(ref newRecord); } } throw; } return newRecord; } internal void SetRowCache(DataRow[] newRows) { rows = newRows; lastFreeRecord = rows.Length; recordCapacity = lastFreeRecord; } [Conditional("DEBUG")] internal void VerifyRecord(int record) { Debug.Assert((record < lastFreeRecord) && (-1 == freeRecordList.IndexOf(record)), "accesing free record"); Debug.Assert((null == rows[record]) || (record == rows[record].oldRecord) || (record == rows[record].newRecord) || (record == rows[record].tempRecord), "record of a different row"); } [Conditional("DEBUG")] internal void VerifyRecord(int record, DataRow row) { Debug.Assert((record < lastFreeRecord) && (-1 == freeRecordList.IndexOf(record)), "accesing free record"); Debug.Assert((null == rows[record]) || (row == rows[record]), "record of a different row"); } } } // 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
- ForceCopyBuildProvider.cs
- CompiledQuery.cs
- ProviderCollection.cs
- MembershipUser.cs
- BamlLocalizationDictionary.cs
- BindingListCollectionView.cs
- TimeEnumHelper.cs
- AutoResetEvent.cs
- Int16Animation.cs
- RightNameExpirationInfoPair.cs
- Options.cs
- MouseDevice.cs
- WindowsSidIdentity.cs
- TypedRowGenerator.cs
- NonDualMessageSecurityOverHttp.cs
- PageParser.cs
- SubqueryTrackingVisitor.cs
- PtsCache.cs
- ScriptComponentDescriptor.cs
- PageBreakRecord.cs
- HotSpotCollection.cs
- PropertyIDSet.cs
- XmlSchemaSimpleTypeRestriction.cs
- TraceXPathNavigator.cs
- ForeignKeyConstraint.cs
- MemoryMappedView.cs
- GridViewRowPresenterBase.cs
- GridItemCollection.cs
- BindingMemberInfo.cs
- srgsitem.cs
- DrawingGroupDrawingContext.cs
- AccessKeyManager.cs
- SignatureDescription.cs
- InkPresenterAutomationPeer.cs
- ActivityTypeDesigner.xaml.cs
- TcpHostedTransportConfiguration.cs
- ITextView.cs
- Type.cs
- GridViewColumnHeaderAutomationPeer.cs
- ProgressChangedEventArgs.cs
- followingsibling.cs
- WindowsFormsLinkLabel.cs
- SQLDecimal.cs
- Baml2006KnownTypes.cs
- ConstantSlot.cs
- RoleGroupCollection.cs
- TableStyle.cs
- DrawingAttributesDefaultValueFactory.cs
- KoreanCalendar.cs
- RoutedPropertyChangedEventArgs.cs
- Label.cs
- CharAnimationUsingKeyFrames.cs
- FloaterBaseParaClient.cs
- TypeConverterValueSerializer.cs
- InputLanguageCollection.cs
- RemoteHelper.cs
- MediaPlayerState.cs
- PasswordPropertyTextAttribute.cs
- DbMetaDataColumnNames.cs
- MainMenu.cs
- DataGridColumnHeaderAutomationPeer.cs
- StateMachineAction.cs
- XmlLanguageConverter.cs
- StorageScalarPropertyMapping.cs
- ProcessHost.cs
- SimpleHandlerBuildProvider.cs
- DesignerCommandAdapter.cs
- initElementDictionary.cs
- AdRotator.cs
- followingsibling.cs
- RectangleF.cs
- DetailsViewModeEventArgs.cs
- HotSpot.cs
- TextRangeEditLists.cs
- SystemInformation.cs
- ComponentEditorPage.cs
- WebPartAddingEventArgs.cs
- BaseAutoFormat.cs
- SharedPerformanceCounter.cs
- RealizationContext.cs
- HashCodeCombiner.cs
- PrintController.cs
- OrderByQueryOptionExpression.cs
- LockCookie.cs
- VariantWrapper.cs
- __ComObject.cs
- PolyQuadraticBezierSegment.cs
- DockingAttribute.cs
- SafeEventHandle.cs
- ClonableStack.cs
- MetadataArtifactLoaderCompositeFile.cs
- ThreadSafeList.cs
- Transform.cs
- SafeFileMapViewHandle.cs
- TdsParserStaticMethods.cs
- Range.cs
- Convert.cs
- Triangle.cs
- IndexerHelper.cs
- QuaternionRotation3D.cs