private Table tTable; // null: memory row; otherwise: cached table #endregion Fields #region Constructors public Row(Table table, object[] o) { tTable = table; int index = tTable.IndexCount; nFirstIndex = new Node(this, 0); Node n = nFirstIndex; for (int i = 1; i < index; i++) { n.nNext = new Node(this, i); n = n.nNext; } oData = o; if (tTable != null && tTable.cCache != null) { LastAccess = CurrentAccess++; // todo: 32 bytes overhead for each index + iSize, iPos Size = 8 + Column.GetSize(o, tTable) + 16 * tTable.IndexCount; //((iSize + 7) / 8) * 8; // align to 8 byte blocks tTable.cCache.Add(this); } Changed = true; }
private void Set(Node x, bool w, Node n) { if (w) { x.SetLeft(n); } else { x.SetRight(n); } if (n != null) { n.SetParent(x); } }
private void Replace(Node x, Node n) { if (x.Equals(_root)) { _root = n; if (n != null) { n.SetParent(null); } } else { Set(x.GetParent(), From(x), n); } }
private bool From(Node x) { if (x.Equals(_root)) { return true; } if (TracingHelper.AssertEnabled) { TracingHelper.Assert(x.GetParent() != null); } return x.Equals(x.GetParent().GetLeft()); }
private Node Child(Node x, bool w) { return w ? x.GetLeft() : x.GetRight(); }
public Node Next(Node x) { if ((++_needCleanUp & 127) == 0) { x.rData.CleanUpCache(); } Node r = x.GetRight(); if (r != null) { x = r; Node l = x.GetLeft(); while (l != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } x = l; l = x.GetLeft(); } return x; } Node ch = x; x = x.GetParent(); while (x != null && ch.Equals(x.GetRight())) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } ch = x; x = x.GetParent(); } return x; }
public void Insert(Node i) { object[] data = i.GetData(); Node n = _root, x = n; bool way = true; int compare = -1; while (true) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } if (n == null) { if (x == null) { _root = i; return; } Set(x, way, i); break; } x = n; compare = CompareRow(data, x.GetData()); TracingHelper.Check(compare != 0, TracingHelper.VIOLATION_OF_UNIQUE_INDEX); way = compare < 0; n = Child(x, way); } while (true) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } int sign = way ? 1 : -1; switch (x.GetBalance() * sign) { case 1: x.SetBalance(0); return; case 0: x.SetBalance(-sign); break; case -1: Node l = Child(x, way); if (l.GetBalance() == -sign) { Replace(x, l); Set(x, way, Child(l, !way)); Set(l, !way, x); x.SetBalance(0); l.SetBalance(0); } else { Node r = Child(l, !way); Replace(x, r); Set(l, !way, Child(r, way)); Set(r, way, l); Set(x, way, Child(r, !way)); Set(r, !way, x); int rb = r.GetBalance(); x.SetBalance((rb == -sign) ? sign : 0); l.SetBalance((rb == sign) ? -sign : 0); r.SetBalance(0); } return; } if (x.Equals(_root)) { return; } way = From(x); x = x.GetParent(); } }
public void Delete(object[] row, bool datatoo) { Node x = Search(row); if (x == null) { return; } Node n; if (x.GetLeft() == null) { n = x.GetRight(); } else if (x.GetRight() == null) { n = x.GetLeft(); } else { Node d = x; x = x.GetLeft(); // todo: this can be improved while (x.GetRight() != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } x = x.GetRight(); } // x will be replaced with n later n = x.GetLeft(); // swap d and x int b = x.GetBalance(); x.SetBalance(d.GetBalance()); d.SetBalance(b); // set x.parent Node xp = x.GetParent(); Node dp = d.GetParent(); if (d == _root) { _root = x; } x.SetParent(dp); if (dp != null) { if (dp.GetRight().Equals(d)) { dp.SetRight(x); } else { dp.SetLeft(x); } } // for in-memory tables we could use: d.rData=x.rData; // but not for cached tables // relink d.parent, x.left, x.right if (xp == d) { d.SetParent(x); if (d.GetLeft().Equals(x)) { x.SetLeft(d); x.SetRight(d.GetRight()); } else { x.SetRight(d); x.SetLeft(d.GetLeft()); } } else { d.SetParent(xp); xp.SetRight(d); x.SetRight(d.GetRight()); x.SetLeft(d.GetLeft()); } x.GetRight().SetParent(x); x.GetLeft().SetParent(x); // set d.left, d.right d.SetLeft(n); if (n != null) { n.SetParent(d); } d.SetRight(null); x = d; } bool way = From(x); Replace(x, n); n = x.GetParent(); x.Delete(); if (datatoo) { x.rData.Delete(); } while (n != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } x = n; int sign = way ? 1 : -1; switch (x.GetBalance() * sign) { case -1: x.SetBalance(0); break; case 0: x.SetBalance(sign); return; case 1: Node r = Child(x, !way); int b = r.GetBalance(); if (b * sign >= 0) { Replace(x, r); Set(x, !way, Child(r, way)); Set(r, way, x); if (b == 0) { x.SetBalance(sign); r.SetBalance(-sign); return; } x.SetBalance(0); r.SetBalance(0); x = r; } else { Node l = Child(r, way); Replace(x, l); b = l.GetBalance(); Set(r, way, Child(l, !way)); Set(l, !way, r); Set(x, !way, Child(l, way)); Set(l, way, x); x.SetBalance((b == sign) ? -sign : 0); r.SetBalance((b == -sign) ? sign : 0); l.SetBalance(0); x = l; } break; } way = From(x); n = x.GetParent(); } }
internal Row(Table t, BinaryReader din, int pos, Row before) { tTable = t; int index = tTable.IndexCount; Pos = pos; nFirstIndex = new Node(this, din, 0); Node n = nFirstIndex; for (int i = 1; i < index; i++) { n.nNext = new Node(this, din, i); n = n.nNext; } int l = tTable.InternalColumnCount; oData = Column.ReadData(din, l); int iCurrent = din.ReadInt32(); LogHelper.Publish( String.Format("Row read with {0} columns. Row read position from file: {1}. Current position: {2}.", oData.Length, iCurrent, Pos ), LogEntryType.Debug ); TracingHelper.Check(iCurrent == Pos, TracingHelper.INPUTSTREAM_ERROR); Insert(before); LastAccess = CurrentAccess++; }
public bool Next() { if (bOuterJoin && nCurrent == null) { return false; } nCurrent = iIndex.Next(nCurrent); while (nCurrent != null) { oCurrentData = nCurrent.GetData(); if (!Test(eEnd)) { break; } if (Test(eAnd)) { return true; } nCurrent = iIndex.Next(nCurrent); } oCurrentData = oEmptyData; return false; }
public bool FindFirst() { if (iIndex == null) { iIndex = tTable.PrimaryIndex; } if (eStart == null) { nCurrent = iIndex.First(); } else { ColumnType type = eStart.Arg.ColumnType; object o = eStart.Arg2.GetValue(type); nCurrent = iIndex.FindFirst(o, eStart.Type); } while (nCurrent != null) { oCurrentData = nCurrent.GetData(); if (!Test(eEnd)) { break; } if (Test(eAnd)) { return true; } nCurrent = iIndex.Next(nCurrent); } oCurrentData = oEmptyData; if (bOuterJoin) { return true; } return false; }
public bool Equals(Node node) { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(iBalance != -2); // rData.iLastAccess=Row.iCurrentAccess++; } if (TracingHelper.AssertEnabled) { if (node != this) { TracingHelper.Assert(rData.Pos == 0 || node == null || node.rData.Pos != rData.Pos); } else { TracingHelper.Assert(node.rData.Pos == rData.Pos); } } return node == this; }
public void Delete() { iBalance = -2; nLeft = nRight = nParent = null; iLeft = iRight = iParent = 0; }
public void SetRight(Node n) { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(iBalance != -2); } rData.RowChanged(); if (n == null) { iRight = 0; nRight = null; } else if (n.rData.Pos != 0) { iRight = n.rData.Pos; } else { nRight = n; } }