2 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 using System.Collections;
26 namespace System.Data.Common
28 internal class RecordCache {
31 const int MIN_CACHE_SIZE = 128;
33 Stack _records = new Stack (16);
34 int _nextFreeIndex = 0;
35 int _currentCapacity = 0;
37 DataRow [] _rowsToRecords;
43 internal RecordCache (DataTable table)
46 _rowsToRecords = table.NewRowArray (16);
49 #endregion //Constructors
53 internal int CurrentCapacity {
54 get { return _currentCapacity; }
57 internal DataRow this [int index] {
58 get { return _rowsToRecords [index]; }
61 _rowsToRecords [index] = value;
65 #endregion // Properties
69 internal int NewRecord ()
71 if (_records.Count > 0)
72 return (int) _records.Pop ();
74 DataColumnCollection cols = _table.Columns;
75 if (_nextFreeIndex >= _currentCapacity) {
76 _currentCapacity *= 2;
77 if (_currentCapacity < MIN_CACHE_SIZE)
78 _currentCapacity = MIN_CACHE_SIZE;
80 for (int i = 0; i < cols.Count; ++i)
81 cols [i].DataContainer.Capacity = _currentCapacity;
83 DataRow [] old = _rowsToRecords;
84 _rowsToRecords = _table.NewRowArray (_currentCapacity);
85 Array.Copy (old, 0, _rowsToRecords, 0, old.Length);
87 return _nextFreeIndex++;
90 internal void DisposeRecord (int index)
93 throw new ArgumentException ();
95 if (!_records.Contains (index))
96 _records.Push (index);
101 // FIXME: This doesn't seem to be the right class to have this method
102 internal int CopyRecord (DataTable fromTable, int fromRecordIndex, int toRecordIndex)
104 int recordIndex = toRecordIndex;
105 if (toRecordIndex == -1)
106 recordIndex = NewRecord ();
109 foreach (DataColumn toColumn in _table.Columns) {
110 DataColumn fromColumn = fromTable.Columns [toColumn.ColumnName];
111 if (fromColumn != null)
112 toColumn.DataContainer.CopyValue (fromColumn.DataContainer, fromRecordIndex, recordIndex);
114 toColumn.DataContainer.CopyValue (_table.DefaultValuesRowIndex, recordIndex);
118 if (toRecordIndex == -1)
119 DisposeRecord (recordIndex);
125 // FIXME: This doesn't seem to be the right class to have this method
126 internal void ReadIDataRecord (int recordIndex, IDataRecord record, int [] mapping, int length)
128 if (mapping.Length > _table.Columns.Count)
129 throw new ArgumentException ();
132 for(; i < length; i++) {
133 DataColumn column = _table.Columns [mapping [i]];
134 column.DataContainer.SetItemFromDataRecord (recordIndex, record, i);
137 for (; i < mapping.Length; i++) {
138 DataColumn column = _table.Columns [mapping [i]];
139 if (column.AutoIncrement)
140 column.DataContainer [recordIndex] = column.AutoIncrementValue ();
142 column.DataContainer [recordIndex] = column.DefaultValue;
146 #endregion // Methods