RecordManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Data / System / Data / RecordManager.cs / 1 / 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 List freeRecordList = 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 List freeRecordList = 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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK