static RowSetEntry RowSetEntryMerge(RowSetEntry a, RowSetEntry b) { RowSetEntry head = new RowSetEntry(); RowSetEntry tail = head; while (a != null && b != null) { Debug.Assert(a.Right == null || a.V <= a.Right.V); Debug.Assert(b.Right == null || b.V <= b.Right.V); if (a.V < b.V) { tail.Right = a; a = a.Right; tail = tail.Right; } else if (b.V < a.V) { tail.Right = b; b = b.Right; tail = tail.Right; } else { a = a.Right; } } if (a != null) { Debug.Assert(a.Right == null || a.V <= a.Right.V); tail.Right = a; } else { Debug.Assert(b == null || b.Right == null || b.V <= b.Right.V); tail.Right = b; } return(head.Right); }
static void RowSetTreeToList(RowSetEntry parent, ref RowSetEntry first, ref RowSetEntry last) { Debug.Assert(parent != null); if (parent.Left != null) { RowSetEntry p = new RowSetEntry(); RowSetTreeToList(parent.Left, ref first, ref p); p.Right = parent; } else { first = parent; } if (parent.Right != null) { RowSetTreeToList(parent.Right, ref parent.Right, ref last); } else { last = parent; } Debug.Assert((last).Right == null); }
static RowSetEntry RowSetEntrySort(RowSetEntry p) { uint i; RowSetEntry next; RowSetEntry[] buckets = new RowSetEntry[40]; while (p != null) { next = p.Right; p.Right = null; for (i = 0; buckets[i] != null; i++) { p = RowSetEntryMerge(buckets[i], p); buckets[i] = null; } buckets[i] = p; p = next; } p = null; for (i = 0; i < buckets.Length; i++) { p = RowSetEntryMerge(p, buckets[i]); } return(p); }
public static bool RowSet_Test(RowSet rowSet, byte batch, long rowid) { // This routine is never called after sqlite3RowSetNext() Debug.Assert(rowSet != null && (rowSet.Flags & ROWSET.NEXT) == 0); // Sort entries into the forest on the first test of a new batch RowSetEntry p, tree; if (batch != rowSet.Batch) { p = rowSet.Entry; if (p != null) { RowSetEntry prevTree = rowSet.Forest; if ((rowSet.Flags & ROWSET.SORTED) == 0) { p = RowSetEntrySort(p); } for (tree = rowSet.Forest; tree != null; tree = tree.Right) { prevTree = tree.Right; if (tree.Left == null) { tree.Left = RowSetListToTree(p); break; } else { RowSetEntry aux = new RowSetEntry(), tail = new RowSetEntry(); RowSetTreeToList(tree.Left, ref aux, ref tail); tree.Left = null; p = RowSetEntryMerge(aux, p); } } if (tree == null) { prevTree = tree = RowSetEntryAlloc(rowSet); if (tree != null) { tree.V = 0; tree.Right = null; tree.Left = RowSetListToTree(p); } } rowSet.Entry = null; rowSet.Last = null; rowSet.Flags |= ROWSET.SORTED; } rowSet.Batch = batch; } // Test to see if the iRowid value appears anywhere in the forest. Return 1 if it does and 0 if not. for (tree = rowSet.Forest; tree != null; tree = tree.Right) { p = tree.Left; while (p != null) { if (p.V < rowid) { p = p.Right; } else if (p.V > rowid) { p = p.Left; } else { return(true); } } } return(false); }