2 using System.Collections;
7 /// Summary description for Index.
13 private DataTable _table;
14 private DataColumn[] _columns;
17 private string _indexName;
21 internal Index (string name, DataTable table, DataColumn[] columns,
31 internal void SetUnique (bool unique)
62 internal bool IsUnique
70 internal DataColumn[] Columns
74 return _columns; // todo: this gives back also primary key field!
78 internal bool IsEquivalent (Index index)
81 if (_unique == index._unique
82 && _columns.Length == index._columns.Length) {
83 for (int j = 0; j < _columns.Length; j++) {
84 if (_columns[j] != index._columns[j]) {
95 internal void Insert (Node i, DataRowVersion version)
102 bool needBalance = true;
117 DataRow nData = n.Row;
125 compare = CompareRow(data, version, nData);
128 throw new ConstraintException("Unique key violation");
141 private void Balance(Node x, bool way)
149 switch (x.GetBalance() * sign) {
161 Node l = Child(x, way);
163 if (l.GetBalance() == -sign) {
165 Set(x, way, Child(l, !way));
171 Node r = Child(l, !way);
174 Set(l, !way, Child(r, way));
176 Set(x, way, Child(r, !way));
179 int rb = r.GetBalance();
181 x.SetBalance((rb == -sign) ? sign
183 l.SetBalance((rb == sign) ? -sign
191 if (x.Equals(_root)) {
200 internal void Delete (DataRow row)
202 Node x = Search(row,DataRowVersion.Current);
206 internal void Delete(Node x)
214 if (x.Left == null) {
217 else if (x.Right == null) {
225 // todo: this can be improved
226 while (x.Right != null) {
230 // x will be replaced with n later
234 int b = x.GetBalance();
236 x.SetBalance(d.GetBalance());
250 if (dp.Right.Equals(d)) {
258 // for in-memory tables we could use: d.rData=x.rData;
259 // but not for cached tables
260 // relink d.parent, x.left, x.right
264 if (d.Left.Equals(x)) {
283 // set d.left, d.right
308 switch (x.GetBalance() * sign) {
320 Node r = Child(x, !way);
321 int b = r.GetBalance();
325 Set(x, !way, Child(r, way));
341 Node l = Child(r, way);
347 Set(r, way, Child(l, !way));
349 Set(x, !way, Child(l, way));
351 x.SetBalance((b == sign) ? -sign
353 r.SetBalance((b == -sign) ? sign
367 internal Node[] FindAllSimple(Object[] indexcoldata)
369 ArrayList nodes = new ArrayList();
370 Node n = FindSimple (indexcoldata, true);
373 while (n != null && ComparePartialRowNonUnique(indexcoldata, n.Row) == 0) {
378 return (Node[])nodes.ToArray (typeof (Node));
381 internal Node FindSimple(Object[] indexcoldata, bool first)
386 if (indexcoldata[0] == null) {
392 int i = this.ComparePartialRowNonUnique(indexcoldata, x.Row);
395 if (first == false) {
399 else if (result == x) {
423 internal Node Find(DataRow data, DataRowVersion version)
429 int i = CompareRow(data, version, x.Row);
451 // internal Node FindFirst(Object value, int compare)
456 // // if (compare == Expression.BIGGER) {
460 // while (x != null) {
461 // bool t = CompareValue(value, x.GetData()[0]) >= iTest;
484 // while (x != null && CompareValue(value, x.GetData()[0]) >= iTest) {
491 // internal Node First()
497 // while (l != null) {
506 internal Node Next(Node x)
532 while (x != null && ch.Equals(x.Right)) {
541 private Node Child(Node x, bool w)
547 private void Replace(Node x, Node n)
550 if (x.Equals(_root)) {
558 Set(x.Parent, x.From(), n);
562 private void Set(Node x, bool w, Node n)
576 private Node Search(DataRow r,DataRowVersion version)
582 int c = CompareRow(r, version, x.Row);
598 internal int ComparePartialRowNonUnique(object[] a, DataRow b)
600 int i = DataColumn.CompareValues(a[0], b[_columns[0].Ordinal, DataRowVersion.Current], _columns[0].DataType, !_columns[0].Table.CaseSensitive);
606 int fieldcount = _columns.Length;
608 for (int j = 1; j < a.Length && j < fieldcount; j++) {
615 i = DataColumn.CompareValues(o, b[_columns[j].Ordinal, DataRowVersion.Current], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
625 // private int CompareRowNonUnique(DataRow a, DataRow b)
630 // int i = DataColumn.CompareValues(a[0], GetNodeValue(b,0), _columns[0].DataType, !_columns[0].Table.CaseSensitive);
636 // int fieldcount = _columns.Length;
638 // for (int j = 1; j < fieldcount; j++) {
639 // i = DataColumn.CompareValues(a[_columns[j].Ordinal], b[_columns[j].Ordinal], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
649 private int CompareRow(DataRow a, DataRowVersion version, DataRow b)
655 for (int j = 0; j < _columns.Length; j++) {
656 i = DataColumn.CompareValues(a[_columns[j].Ordinal, version], b[_columns[j].Ordinal, DataRowVersion.Current], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
666 // private int CompareValue(Object a, Object b)
668 // if (a == DBNull.Value) {
669 // if (b == DBNull.Value)
674 // if (b == DBNull.Value)
677 // return System.Data.Common.DBComparerFactory.GetComparer(b.GetType(), false).Compare(a, b);
681 // /// When we are inspectiong node (row) value in the index
682 // /// we are alway referencing its Current value
684 // private object GetNodeValue(DataRow row,DataColumn column)
686 // return row[column,DataRowVersion.Current];
690 // /// When we are inspectiong node (row) value in the index
691 // /// we are alway referencing its Current value
693 // private object GetNodeValue(DataRow row,index idx)
695 // return row[idx,DataRowVersion.Current];
698 // internal String GetString()
700 // System.Text.StringBuilder sb = new System.Text.StringBuilder();
701 // for(int i =0; i < this._columns.Length; i++) {
702 // sb.Append("[ " + _columns[i].ColumnName + " ] ");
705 // if(this.Root != null) {
706 // this.Root.CollectString(sb,0);
708 // return sb.ToString();