2 using System.Collections;
8 public Node (DataRow row) {
15 public int GetBalance () { return 0; }
16 public void SetBalance (int i) { }
17 public bool From () { return false; }
18 public void Delete () {}
21 internal class DBComparerFactory
23 public static IComparer GetComparer (Type t, bool b) { return null; }
27 /// Summary description for Index.
33 private DataTable _table;
34 private DataColumn[] _columns;
37 private string _indexName;
41 internal Index (string name, DataTable table, DataColumn[] columns,
51 internal void SetUnique (bool unique)
82 internal bool IsUnique
90 internal DataColumn[] Columns
94 return _columns; // todo: this gives back also primary key field!
98 internal bool IsEquivalent (Index index)
101 if (_unique == index._unique
102 && _columns.Length == index._columns.Length) {
103 for (int j = 0; j < _columns.Length; j++) {
104 if (_columns[j] != index._columns[j]) {
115 internal void Insert (Node i, DataRowVersion version)
117 DataRow data = i.Row;
122 bool needBalance = true;
137 DataRow nData = n.Row;
145 compare = CompareRow(data, version, nData);
148 throw new ConstraintException("Unique key violation");
161 private void Balance(Node x, bool way)
169 switch (x.GetBalance() * sign) {
181 Node l = Child(x, way);
183 if (l.GetBalance() == -sign) {
185 Set(x, way, Child(l, !way));
191 Node r = Child(l, !way);
194 Set(l, !way, Child(r, way));
196 Set(x, way, Child(r, !way));
199 int rb = r.GetBalance();
201 x.SetBalance((rb == -sign) ? sign
203 l.SetBalance((rb == sign) ? -sign
211 if (x.Equals(_root)) {
220 internal void Delete (DataRow row)
222 Node x = Search(row,DataRowVersion.Current);
226 internal void Delete(Node x)
234 if (x.Left == null) {
237 else if (x.Right == null) {
245 // todo: this can be improved
246 while (x.Right != null) {
250 // x will be replaced with n later
254 int b = x.GetBalance();
256 x.SetBalance(d.GetBalance());
270 if (dp.Right.Equals(d)) {
278 // for in-memory tables we could use: d.rData=x.rData;
279 // but not for cached tables
280 // relink d.parent, x.left, x.right
284 if (d.Left.Equals(x)) {
303 // set d.left, d.right
328 switch (x.GetBalance() * sign) {
340 Node r = Child(x, !way);
341 int b = r.GetBalance();
345 Set(x, !way, Child(r, way));
361 Node l = Child(r, way);
367 Set(r, way, Child(l, !way));
369 Set(x, !way, Child(l, way));
371 x.SetBalance((b == sign) ? -sign
373 r.SetBalance((b == -sign) ? sign
387 internal Node[] FindAllSimple(Object[] indexcoldata)
389 ArrayList nodes = new ArrayList();
390 Node n = FindSimple (indexcoldata, true);
393 while (n != null && ComparePartialRowNonUnique(indexcoldata, n.Row) == 0) {
398 return (Node[])nodes.ToArray (typeof (Node));
401 internal Node FindSimple(Object[] indexcoldata, bool first)
406 if (indexcoldata[0] == null) {
412 int i = this.ComparePartialRowNonUnique(indexcoldata, x.Row);
415 if (first == false) {
419 else if (result == x) {
443 internal Node Find(DataRow data, DataRowVersion version)
449 int i = CompareRow(data, version, x.Row);
471 // internal Node FindFirst(Object value, int compare)
476 // // if (compare == Expression.BIGGER) {
480 // while (x != null) {
481 // bool t = CompareValue(value, x.GetData()[0]) >= iTest;
504 // while (x != null && CompareValue(value, x.GetData()[0]) >= iTest) {
511 // internal Node First()
517 // while (l != null) {
526 internal Node Next(Node x)
552 while (x != null && ch.Equals(x.Right)) {
561 private Node Child(Node x, bool w)
567 private void Replace(Node x, Node n)
570 if (x.Equals(_root)) {
578 Set(x.Parent, x.From(), n);
582 private void Set(Node x, bool w, Node n)
596 private Node Search(DataRow r,DataRowVersion version)
602 int c = CompareRow(r, version, x.Row);
618 internal int ComparePartialRowNonUnique(object[] a, DataRow b)
621 int i = DataColumn.CompareValues(a[0], b[0, DataRowVersion.Current], _columns[0].DataType, !_columns[0].Table.CaseSensitive);
627 int fieldcount = _columns.Length;
629 for (int j = 1; j < a.Length && j < fieldcount; j++) {
636 i = DataColumn.CompareValues(o, b[_columns[j].Ordinal, DataRowVersion.Current], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
646 // private int CompareRowNonUnique(DataRow a, DataRow b)
651 // int i = DataColumn.CompareValues(a[0], GetNodeValue(b,0), _columns[0].DataType, !_columns[0].Table.CaseSensitive);
657 // int fieldcount = _columns.Length;
659 // for (int j = 1; j < fieldcount; j++) {
660 // i = DataColumn.CompareValues(a[_columns[j].Ordinal], b[_columns[j].Ordinal], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
670 private int CompareRow(DataRow a, DataRowVersion version, DataRow b)
676 for (int j = 0; j < _columns.Length; j++) {
677 i = DataColumn.CompareValues(a[_columns[j].Ordinal, version], b[_columns[j].Ordinal, DataRowVersion.Current], _columns[j].DataType, !_columns[j].Table.CaseSensitive);
687 // private int CompareValue(Object a, Object b)
689 // if (a == DBNull.Value) {
690 // if (b == DBNull.Value)
695 // if (b == DBNull.Value)
698 // return System.Data.Common.DBComparerFactory.GetComparer(b.GetType(), false).Compare(a, b);
702 // /// When we are inspectiong node (row) value in the index
703 // /// we are alway referencing its Current value
705 // private object GetNodeValue(DataRow row,DataColumn column)
707 // return row[column,DataRowVersion.Current];
711 // /// When we are inspectiong node (row) value in the index
712 // /// we are alway referencing its Current value
714 // private object GetNodeValue(DataRow row,index idx)
716 // return row[idx,DataRowVersion.Current];
719 // internal String GetString()
721 // System.Text.StringBuilder sb = new System.Text.StringBuilder();
722 // for(int i =0; i < this._columns.Length; i++) {
723 // sb.Append("[ " + _columns[i].ColumnName + " ] ");
726 // if(this.Root != null) {
727 // this.Root.CollectString(sb,0);
729 // return sb.ToString();