/* ** Convert a sorted list of elements into a binary tree. Make the tree ** as deep as it needs to be in order to contain the entire list. */ static RowSetEntry rowSetListToTree(RowSetEntry pList) { int iDepth; /* Depth of the tree so far */ RowSetEntry p; /* Current tree root */ RowSetEntry pLeft; /* Left subtree */ Debug.Assert(pList != null); p = pList; pList = p.pRight; p.pLeft = p.pRight = null; for (iDepth = 1; pList != null; iDepth++) { pLeft = p; p = pList; pList = p.pRight; p.pLeft = pLeft; p.pRight = rowSetNDeepTree(ref pList, iDepth); } return(p); }
public RowSetEntry pTree; /* Binary tree of entries */ #endregion Fields #region Constructors public RowSet( sqlite3 db, int N ) { this.pChunk = null; this.db = db; this.pEntry = null; this.pLast = null; this.pFresh = new RowSetEntry[N]; this.pTree = null; this.nFresh = N; this.isSorted = true; this.iBatch = 0; }
/* ** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects. ** Convert this tree into a linked list connected by the pRight pointers ** and return pointers to the first and last elements of the new list. */ static void rowSetTreeToList( RowSetEntry pIn, /* Root of the input tree */ ref RowSetEntry ppFirst, /* Write head of the output list here */ ref RowSetEntry ppLast /* Write tail of the output list here */ ) { Debug.Assert( pIn != null ); if ( pIn.pLeft != null ) { RowSetEntry p = new RowSetEntry(); rowSetTreeToList( pIn.pLeft, ref ppFirst, ref p ); p.pRight = pIn; } else { ppFirst = pIn; } if ( pIn.pRight != null ) { rowSetTreeToList( pIn.pRight, ref pIn.pRight, ref ppLast ); } else { ppLast = pIn; } Debug.Assert( ( ppLast ).pRight == null ); }
/* ** Convert the list in p.pEntry into a sorted list if it is not ** sorted already. If there is a binary tree on p.pTree, then ** convert it into a list too and merge it into the p.pEntry list. */ static void rowSetToList( RowSet p ) { if ( !p.isSorted ) { rowSetSort( p ); } if ( p.pTree != null ) { RowSetEntry pHead = new RowSetEntry(); RowSetEntry pTail = new RowSetEntry(); rowSetTreeToList( p.pTree, ref pHead, ref pTail ); p.pTree = null; p.pEntry = rowSetMerge( p.pEntry, pHead ); } }
/* ** Sort all elements on the pEntry list of the RowSet into ascending order. */ static void rowSetSort( RowSet p ) { u32 i; RowSetEntry pEntry; RowSetEntry[] aBucket = new RowSetEntry[40]; Debug.Assert( p.isSorted == false ); //memset(aBucket, 0, sizeof(aBucket)); while ( p.pEntry != null ) { pEntry = p.pEntry; p.pEntry = pEntry.pRight; pEntry.pRight = null; for ( i = 0; aBucket[i] != null; i++ ) { pEntry = rowSetMerge( aBucket[i], pEntry ); aBucket[i] = null; } aBucket[i] = pEntry; } pEntry = null; for ( i = 0; i < aBucket.Length; i++ )//sizeof(aBucket)/sizeof(aBucket[0]) { pEntry = rowSetMerge( pEntry, aBucket[i] ); } p.pEntry = pEntry; p.pLast = null; p.isSorted = true; }
/* ** Convert a sorted list of elements (connected by pRight) into a binary ** tree with depth of iDepth. A depth of 1 means the tree contains a single ** node taken from the head of *ppList. A depth of 2 means a tree with ** three nodes. And so forth. ** ** Use as many entries from the input list as required and update the ** *ppList to point to the unused elements of the list. If the input ** list contains too few elements, then construct an incomplete tree ** and leave *ppList set to NULL. ** ** Return a pointer to the root of the constructed binary tree. */ static RowSetEntry rowSetNDeepTree( ref RowSetEntry ppList, int iDepth ) { RowSetEntry p; /* Root of the new tree */ RowSetEntry pLeft; /* Left subtree */ if ( ppList == null ) { return null; } if ( iDepth == 1 ) { p = ppList; ppList = p.pRight; p.pLeft = p.pRight = null; return p; } pLeft = rowSetNDeepTree( ref ppList, iDepth - 1 ); p = ppList; if ( p == null ) { return pLeft; } p.pLeft = pLeft; ppList = p.pRight; p.pRight = rowSetNDeepTree( ref ppList, iDepth - 1 ); return p; }
/* ** Merge two lists of RowSetEntry objects. Remove duplicates. ** ** The input lists are connected via pRight pointers and are ** assumed to each already be in sorted order. */ static RowSetEntry rowSetMerge( RowSetEntry pA, /* First sorted list to be merged */ RowSetEntry pB /* Second sorted list to be merged */ ) { RowSetEntry head = new RowSetEntry(); RowSetEntry pTail; pTail = head; while ( pA != null && pB != null ) { Debug.Assert( pA.pRight == null || pA.v <= pA.pRight.v ); Debug.Assert( pB.pRight == null || pB.v <= pB.pRight.v ); if ( pA.v < pB.v ) { pTail.pRight = pA; pA = pA.pRight; pTail = pTail.pRight; } else if ( pB.v < pA.v ) { pTail.pRight = pB; pB = pB.pRight; pTail = pTail.pRight; } else { pA = pA.pRight; } } if ( pA != null ) { Debug.Assert( pA.pRight == null || pA.v <= pA.pRight.v ); pTail.pRight = pA; } else { Debug.Assert( pB == null || pB.pRight == null || pB.v <= pB.pRight.v ); pTail.pRight = pB; } return head.pRight; }
/* ** Convert a sorted list of elements into a binary tree. Make the tree ** as deep as it needs to be in order to contain the entire list. */ static RowSetEntry rowSetListToTree( RowSetEntry pList ) { int iDepth; /* Depth of the tree so far */ RowSetEntry p; /* Current tree root */ RowSetEntry pLeft; /* Left subtree */ Debug.Assert( pList != null ); p = pList; pList = p.pRight; p.pLeft = p.pRight = null; for ( iDepth = 1; pList != null; iDepth++ ) { pLeft = p; p = pList; pList = p.pRight; p.pLeft = pLeft; p.pRight = rowSetNDeepTree( ref pList, iDepth ); } return p; }