public bool CanRemove() { Node n = nFirstIndex; while (n != null) { if (TracingHelper.AssertEnabled) { TracingHelper.Assert(n.iBalance != -2); } if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } if (n.iParent == 0 && n.nParent == null) { return(true); } n = n.nNext; } return(false); }
private Node Search(object[] d) { Node x = _root; while (x != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } int c = CompareRow(d, x.GetData()); if (c == 0) { return(x); } else if (c < 0) { x = x.GetLeft(); } else { x = x.GetRight(); } } return(null); }
/// <summary> /// CleanUp method declaration. /// This method cleans up the cache when it grows too large. It works by /// checking Rows in held in the Cache's iLastAccess member and removing /// Rows that haven't been accessed in the longest time. /// </summary> public void CleanUp() { if (_cacheSize < MAX_CACHE_SIZE) { return; } int count = 0, j = 0; while (j++ < LENGTH && _cacheSize + LENGTH > MAX_CACHE_SIZE && (count * 16) < LENGTH) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } Row r = GetWorst(); if (r == null) { return; } if (r.Changed) { _rowWriter[count++] = r; } else { // here we can't remove roots if (!r.CanRemove()) { Remove(r); } } } if (count != 0) { SaveSorted(count); } for (int i = 0; i < count; i++) { // here we can't remove roots Row r = _rowWriter[i]; if (!r.CanRemove()) { Remove(r); } _rowWriter[i] = null; } }
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 Node First() { Node x = _root, l = x; while (l != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } x = l; l = x.GetLeft(); } return(x); }
/// <summary> /// </summary> private void SaveAll() { if (_rowFirst == null) { return; } Row r = _rowFirst; while (true) { int count = 0; Row begin = r; do { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } if (r.Changed) { _rowWriter[count++] = r; } r = r.Next; } while (r != begin && count < LENGTH); if (count == 0) { return; } SaveSorted(count); for (int i = 0; i < count; i++) { _rowWriter[i] = null; } } }
public void MoveData(Table from) { Index index = from.PrimaryIndex; Node n = index.First(); while (n != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } object[] o = n.GetData(); InsertNoCheck(o, null); n = index.Next(n); } index = PrimaryIndex; n = index.First(); while (n != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } object[] o = n.GetData(); from.DeleteNoCheck(o, null); n = index.Next(n); } }
public Node Find(object[] data) { Node x = _root, n; while (x != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } int i = CompareRowNonUnique(data, x.GetData()); if (i == 0) { return(x); } else if (i > 0) { n = x.GetRight(); } else { n = x.GetLeft(); } if (n == null) { return(null); } x = n; } return(null); }
/// <summary> /// </summary> private static void Sort(Row[] w, int l, int r) { int i, j, p; while (r - l > 10) { i = (r + l) >> 1; if (w[l].Pos > w[r].Pos) { Swap(w, l, r); } if (w[i].Pos < w[l].Pos) { Swap(w, l, i); } else if (w[i].Pos > w[r].Pos) { Swap(w, i, r); } j = r - 1; Swap(w, i, j); p = w[j].Pos; i = l; while (true) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } while (w[++i].Pos < p) { ; } while (w[--j].Pos > p) { ; } if (i >= j) { break; } Swap(w, i, j); } Swap(w, i, r - 1); Sort(w, l, i - 1); l = i + 1; } for (i = l + 1; i <= r; i++) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } Row t = w[i]; for (j = i - 1; j >= l && w[j].Pos > t.Pos; j--) { w[j + 1] = w[j]; } w[j + 1] = t; } }
/// <summary> /// GetRow method declaration. /// This method reads a Row object from the cache. /// </summary> /// <param name="pos">Offset of the requested Row in the cache</param> /// <param name="table">Table this Row belongs to</param> /// <returns>The Row object as read from the cache.</returns> public Row GetRow(int pos, Table table) { int k = pos & MASK; Row r = _rowData[k]; Row start = r; while (r != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } int p = r.Pos; if (p == pos) { return(r); } else if ((p & MASK) != k) { break; } r = r.Next; if (r == start) { break; } } Row before = _rowData[k]; if (before == null) { before = _rowFirst; } try { LogHelper.Publish(String.Format("Retrieving row at position: {0}.", pos), LogEntryType.Debug); _fileStream.Seek(pos, SeekOrigin.Begin); BinaryReader b = new BinaryReader(_fileStream); int size = b.ReadInt32(); byte[] buffer = new byte[size]; buffer = b.ReadBytes(size); LogHelper.Publish(String.Format("Row Size: {0}. Retrieved {1} bytes.", size, buffer.Length), LogEntryType.Debug); MemoryStream bin = new MemoryStream(buffer); BinaryReader din = new BinaryReader(bin, System.Text.Encoding.Unicode); r = new Row(table, din, pos, before); r.Size = size; } catch (IOException e) { #if !POCKETPC Console.WriteLine(e.StackTrace); #endif throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, "reading: " + e); } _cacheSize++; _rowData[k] = r; _rowFirst = r; return(r); }
/// <summary> /// Add method declaration. /// This method adds a Row to the Cache. It walks the /// list of CacheFree objects to see if there is available space /// to store the new Row, reusing space if it exists, otherwise /// we grow the file. /// </summary> /// <param name="row">Row to be added to Cache</param> public void Add(Row row) { int size = row.Size; CacheFree f = _cacheRoot; CacheFree last = null; int i = _freePos; while (f != null) { if (TracingHelper.TraceEnabled) { TracingHelper.Stop(); } // first that is long enough if (f.Length >= size) { i = f.Pos; size = f.Length - size; if (size < 8) { // remove almost empty blocks if (last == null) { _cacheRoot = f.Next; } else { last.Next = f.Next; } _freeCount--; } else { f.Length = size; f.Pos += row.Size; } break; } last = f; f = f.Next; } row.Pos = i; if (i == _freePos) { _freePos += size; } int k = i & MASK; Row before = _rowData[k]; if (before == null) { before = _rowFirst; } row.Insert(before); _cacheSize++; _rowData[k] = row; _rowFirst = row; }
public Node FindFirst(object value, ExpressionType compare) { TracingHelper.Assert(compare == ExpressionType.Bigger || compare == ExpressionType.Equal || compare == ExpressionType.BiggerEqual, "Index.findFirst"); Node x = _root; int iTest = 1; if (compare == ExpressionType.Bigger) { iTest = 0; } while (x != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } bool t = CompareValue(value, x.GetData()[_column_0]) >= iTest; if (t) { Node r = x.GetRight(); if (r == null) { break; } x = r; } else { Node l = x.GetLeft(); if (l == null) { break; } x = l; } } while (x != null && CompareValue(value, x.GetData()[_column_0]) >= iTest) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } x = Next(x); } return(x); }
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(); } }
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(); } }