• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C# BtCursor类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C#中BtCursor的典型用法代码示例。如果您正苦于以下问题:C# BtCursor类的具体用法?C# BtCursor怎么用?C# BtCursor使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



BtCursor类属于命名空间,在下文中一共展示了BtCursor类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。

示例1: CloseCursor

 public static RC CloseCursor(BtCursor cur)
 {
     var btree = cur.Btree;
     if (btree != null)
     {
         var bt = cur.Bt;
         btree.Enter();
         ClearCursor(cur);
         if (cur.Prev != null)
             cur.Prev.Next = cur.Next;
         else
             bt.Cursor = cur.Next;
         if (cur.Next != null)
             cur.Next.Prev = cur.Prev;
         for (var i = 0; i <= cur.ID; i++)
             releasePage(cur.Pages[i]);
         unlockBtreeIfUnused(bt);
         invalidateOverflowCache(cur);
         btree.Leave();
     }
     return RC.OK;
 }
开发者ID:BclEx,项目名称:GpuData,代码行数:22,代码来源:Btree.cs


示例2: sqlite3BtreeLeaveCursor

 //# define sqlite3BtreeLeaveCursor(X)
 static void sqlite3BtreeLeaveCursor( BtCursor X )
 {
 }
开发者ID:Jaden-J,项目名称:csharp-sqlite,代码行数:4,代码来源:Btree_h.cs


示例3: sqlite3VdbeMemFromBtree

		/*
		** Move data out of a btree key or data field and into a Mem structure.
		** The data or key is taken from the entry that pCur is currently pointing
		** to.  offset and amt determine what portion of the data or key to retrieve.
		** key is true to get the key or false to get data.  The result is written
		** into the pMem element.
		**
		** The pMem structure is assumed to be uninitialized.  Any prior content
		** is overwritten without being freed.
		**
		** If this routine fails for any reason (malloc returns NULL or unable
		** to read from the disk) then the pMem is left in an inconsistent state.
		*/

		private static int sqlite3VdbeMemFromBtree(
		BtCursor pCur,    /* Cursor pointing at record to retrieve. */
		int offset,       /* Offset from the start of data to return bytes from. */
		int amt,          /* Number of bytes to return. */
		bool key,         /* If true, retrieve from the btree key, not data. */
		Mem pMem          /* OUT: Return data in this Mem structure. */
		)
		{
			byte[] zData;       /* Data from the btree layer */
			int available = 0; /* Number of bytes available on the local btree page */
			int rc = SQLITE_OK; /* Return code */

			Debug.Assert(sqlite3BtreeCursorIsValid(pCur));

			/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
			** that both the BtShared and database handle mutexes are held. */
			Debug.Assert((pMem.flags & MEM_RowSet) == 0);
			int outOffset = -1;
			if (key)
			{
				zData = sqlite3BtreeKeyFetch(pCur, ref available, ref outOffset);
			}
			else
			{
				zData = sqlite3BtreeDataFetch(pCur, ref available, ref outOffset);
			}
			Debug.Assert(zData != null);

			if (offset + amt <= available && (pMem.flags & MEM_Dyn) == 0)
			{
				sqlite3VdbeMemRelease(pMem);
				pMem.zBLOB = sqlite3Malloc(amt);
				Buffer.BlockCopy(zData, offset, pMem.zBLOB, 0, amt);//pMem.z = &zData[offset];
				pMem.flags = MEM_Blob | MEM_Ephem;
			}
			else if (SQLITE_OK == (rc = sqlite3VdbeMemGrow(pMem, amt + 2, 0)))
			{
				pMem.enc = 0;
				pMem.type = SQLITE_BLOB;
				pMem.z = null;
				pMem.zBLOB = sqlite3Malloc(amt);
				pMem.flags = MEM_Blob | MEM_Dyn | MEM_Term;
				if (key)
				{
					rc = sqlite3BtreeKey(pCur, (u32)offset, (u32)amt, pMem.zBLOB);
				}
				else
				{
					rc = sqlite3BtreeData(pCur, (u32)offset, (u32)amt, pMem.zBLOB);//pMem.z =  pMem_z ;
				}
				//pMem.z[amt] = 0;
				//pMem.z[amt+1] = 0;
				if (rc != SQLITE_OK)
				{
					sqlite3VdbeMemRelease(pMem);
				}
			}
			pMem.n = amt;
			sqlite3_free(ref zData);

			return rc;
		}
开发者ID:broettge,项目名称:MatterControl,代码行数:76,代码来源:vdbemem_c.cs


示例4: sqlite3BtreeLeaveCursor

void sqlite3BtreeLeaveCursor(BtCursor *pCur){
  sqlite3BtreeLeave(pCur->pBtree);
}
开发者ID:broettge,项目名称:MatterControl,代码行数:3,代码来源:btmutex_c.cs


示例5: CursorHints

 public static void CursorHints(BtCursor cur, uint mask)
 {
     Debug.Assert(mask == BTREE_BULKLOAD || mask == 0);
     cur.Hints = (byte)mask;
 }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:5,代码来源:Btree.cs


示例6: PutData

        public static RC PutData(BtCursor cur, uint offset, uint amount, byte[] z)
        {
            Debug.Assert(cursorHoldsMutex(cur));
            Debug.Assert(MutexEx.Held(cur.Btree.Ctx.Mutex));
            Debug.Assert(cur.IsIncrblobHandle);

            RC rc = restoreCursorPosition(cur);
            if (rc != RC.OK)
                return rc;
            Debug.Assert(cur.State != CURSOR.REQUIRESEEK);
            if (cur.State != CURSOR.VALID)
                return RC.ABORT;

            // Check some assumptions: 
            //   (a) the cursor is open for writing,
            //   (b) there is a read/write transaction open,
            //   (c) the connection holds a write-lock on the table (if required),
            //   (d) there are no conflicting read-locks, and
            //   (e) the cursor points at a valid row of an intKey table.
            if (!cur.WrFlag)
                return RC.READONLY;
            Debug.Assert((cur.Bt.BtsFlags & BTS.READ_ONLY) == 0 && cur.Bt.InTransaction == TRANS.WRITE);
            Debug.Assert(hasSharedCacheTableLock(cur.Btree, cur.RootID, false, LOCK.WRITE));
            Debug.Assert(!hasReadConflicts(cur.Btree, cur.RootID));
            Debug.Assert(cur.Pages[cur.ID].IntKey);

            return accessPayload(cur, offset, amount, z, 1);
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:28,代码来源:Btree.cs


示例7: Delete

        public static RC Delete(BtCursor cur)
        {
            Btree p = cur.Btree;
            BtShared bt = p.Bt;
            Debug.Assert(cursorHoldsMutex(cur));
            Debug.Assert(bt.InTransaction == TRANS.WRITE);
            Debug.Assert((bt.BtsFlags & BTS.READ_ONLY) == 0);
            Debug.Assert(cur.WrFlag);
            Debug.Assert(hasSharedCacheTableLock(p, cur.RootID, cur.KeyInfo != null, LOCK.WRITE));
            Debug.Assert(!hasReadConflicts(p, cur.RootID));

            if (C._NEVER(cur.Idxs[cur.ID] >= cur.Pages[cur.ID].Cells) || C._NEVER(cur.State != CURSOR.VALID))
                return RC.ERROR; // Something has gone awry.

            int cellDepth = cur.ID; // Depth of node containing pCell
            uint cellIdx = cur.Idxs[cellDepth]; // Index of cell to delete
            MemPage page = cur.Pages[cellDepth]; // Page to delete cell from
            uint cell_ = findCell(page, cellIdx); // Pointer to cell to delete

            // If the page containing the entry to delete is not a leaf page, move the cursor to the largest entry in the tree that is smaller than
            // the entry being deleted. This cell will replace the cell being deleted from the internal node. The 'previous' entry is used for this instead
            // of the 'next' entry, as the previous entry is always a part of the sub-tree headed by the child page of the cell being deleted. This makes
            // balancing the tree following the delete operation easier.
            RC rc;
            if (!page.Leaf)
            {
                int notUsed = 0;
                rc = Previous(cur, ref notUsed);
                if (rc != RC.OK) return rc;
            }

            // Save the positions of any other cursors open on this table before making any modifications. Make the page containing the entry to be 
            // deleted writable. Then free any overflow pages associated with the entry and finally remove the cell itself from within the page.  
            rc = saveAllCursors(bt, cur.RootID, cur);
            if (rc != RC.OK) return rc;

            // If this is a delete operation to remove a row from a table b-tree, invalidate any incrblob cursors open on the row being deleted.
            if (cur.KeyInfo == null)
                invalidateIncrblobCursors(p, cur.Info.Key, false);

            rc = Pager.Write(page.DBPage);
            if (rc != RC.OK) return rc;
            rc = clearCell(page, cell_);
            dropCell(page, cellIdx, cellSizePtr(page, cell_), ref rc);
            if (rc != RC.OK) return rc;

            // If the cell deleted was not located on a leaf page, then the cursor is currently pointing to the largest entry in the sub-tree headed
            // by the child-page of the cell that was just deleted from an internal node. The cell from the leaf node needs to be moved to the internal
            // node to replace the deleted cell.
            if (!page.Leaf)
            {
                MemPage leaf = cur.Pages[cur.ID];
                Pid n = cur.Pages[cellDepth + 1].ID;

                cell_ = findCell(leaf, (uint)leaf.Cells - 1);
                ushort sizeCell = cellSizePtr(leaf, cell_);
                Debug.Assert(MX_CELL_SIZE(bt) >= sizeCell);

                //allocateTempSpace(bt);
                //byte[] tmp = Bt.TmpSpace;

                rc = Pager.Write(leaf.DBPage);
                { byte[] cell_4 = new byte[sizeCell + 4]; Buffer.BlockCopy(leaf.Data, (int)cell_ - 4, cell_4, 0, (int)sizeCell + 4); insertCell(page, cellIdx, cell_4, (ushort)(sizeCell + 4), null, n, ref rc); }
                dropCell(leaf, (uint)(leaf.Cells - 1), sizeCell, ref rc);
                if (rc != RC.OK) return rc;
            }

            // Balance the tree. If the entry deleted was located on a leaf page, then the cursor still points to that page. In this case the first
            // call to balance() repairs the tree, and the if(...) condition is never true.
            //
            // Otherwise, if the entry deleted was on an internal node page, then pCur is pointing to the leaf page from which a cell was removed to
            // replace the cell deleted from the internal node. This is slightly tricky as the leaf node may be underfull, and the internal node may
            // be either under or overfull. In this case run the balancing algorithm on the leaf node first. If the balance proceeds far enough up the
            // tree that we can be sure that any problem in the internal node has been corrected, so be it. Otherwise, after balancing the leaf node,
            // walk the cursor up the tree to the internal node and balance it as well.
            rc = balance(cur);
            if (rc == RC.OK && cur.ID > cellDepth)
            {
                while (cur.ID > cellDepth)
                    releasePage(cur.Pages[cur.ID--]);
                rc = balance(cur);
            }

            if (rc == RC.OK)
                moveToRoot(cur);
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:87,代码来源:Btree.cs


示例8: saveCursorPosition

        static RC saveCursorPosition(BtCursor cur)
        {
            Debug.Assert(cur.State == CURSOR.VALID);
            Debug.Assert(cur.Key == null);
            Debug.Assert(cursorHoldsMutex(cur));

            var rc = KeySize(cur, ref cur.KeyLength);
            Debug.Assert(rc == RC.OK);  // KeySize() cannot fail

            // If this is an intKey table, then the above call to BtreeKeySize() stores the integer key in pCur.nKey. In this case this value is
            // all that is required. Otherwise, if pCur is not open on an intKey table, then malloc space for and store the pCur.nKey bytes of key data.
            if (!cur.Pages[0].IntKey)
            {
                var key = C._alloc((int)cur.KeyLength);
                rc = Key(cur, 0, (uint)cur.KeyLength, key);
                if (rc == RC.OK)
                    cur.Key = key;
            }
            Debug.Assert(!cur.Pages[0].IntKey || cur.Key == null);

            if (rc == RC.OK)
            {
                btreeReleaseAllCursorPages(cur);
                cur.State = CURSOR.REQUIRESEEK;
            }

            invalidateOverflowCache(cur);
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:29,代码来源:Btree.cs


示例9: Next_

        public static RC Next_(BtCursor cur, ref int res)
        {
            Debug.Assert(cursorHoldsMutex(cur));
            var rc = restoreCursorPosition(cur);
            if (rc != RC.OK)
                return rc;
            if (cur.State == CURSOR.INVALID)
            {
                res = 1;
                return RC.OK;
            }
            if (cur.SkipNext > 0)
            {
                cur.SkipNext = 0;
                res = 0;
                return RC.OK;
            }
            cur.SkipNext = 0;

            MemPage page = cur.Pages[cur.ID];
            uint idx = ++cur.Idxs[cur.ID];
            Debug.Assert(page.IsInit);

            cur.Info.Size = 0;
            cur.ValidNKey = false;
            if (idx >= page.Cells)
            {
                if (!page.Leaf)
                {
                    rc = moveToChild(cur, ConvertEx.Get4(page.Data, page.HdrOffset + 8));
                    if (rc != RC.OK) return rc;
                    rc = moveToLeftmost(cur);
                    res = 0;
                    return rc;
                }
                do
                {
                    if (cur.ID == 0)
                    {
                        res = 1;
                        cur.State = CURSOR.INVALID;
                        return RC.OK;
                    }
                    moveToParent(cur);
                    page = cur.Pages[cur.ID];
                } while (cur.Idxs[cur.ID] >= page.Cells);
                res = 0;
                if (page.IntKey)
                    rc = Next_(cur, ref res);
                else
                    rc = RC.OK;
                return rc;
            }
            res = 0;
            if (page.Leaf)
                return RC.OK;
            rc = moveToLeftmost(cur);
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:59,代码来源:Btree.cs


示例10: Eof

 public static bool Eof(BtCursor cur)
 {
     // TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries have been deleted? This API will need to change to return an error code
     // as well as the boolean result value.
     return (cur.State != CURSOR.VALID);
 }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:6,代码来源:Btree.cs


示例11: btreeReleaseAllCursorPages

 static void btreeReleaseAllCursorPages(BtCursor cur)
 {
     for (int i = 0; i <= cur.ID; i++)
     {
         releasePage(cur.Pages[i]);
         cur.Pages[i] = null;
     }
     cur.ID = -1;
 }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:9,代码来源:Btree.cs


示例12: MovetoUnpacked

        public static RC MovetoUnpacked(BtCursor cur, UnpackedRecord idxKey, long intKey, int biasRight, out int res)
        {
            Debug.Assert(cursorHoldsMutex(cur));
            Debug.Assert(MutexEx.Held(cur.Btree.Ctx.Mutex));
            Debug.Assert((idxKey == null) == (cur.KeyInfo == null));

            // If the cursor is already positioned at the point we are trying to move to, then just return without doing any work
            if (cur.State == CURSOR.VALID && cur.ValidNKey && cur.Pages[0].IntKey)
            {
                if (cur.Info.Key == intKey)
                {
                    res = 0;
                    return RC.OK;
                }
                if (cur.AtLast != 0 && cur.Info.Key < intKey)
                {
                    res = -1;
                    return RC.OK;
                }
            }

            res = -1;
            var rc = moveToRoot(cur);
            if (rc != RC.OK)
                return rc;
            Debug.Assert(cur.RootID == 0 || cur.Pages[cur.ID] != null);
            Debug.Assert(cur.RootID == 0 || cur.Pages[cur.ID].IsInit);
            Debug.Assert(cur.State == CURSOR.INVALID || cur.Pages[cur.ID].Cells > 0);
            if (cur.State == CURSOR.INVALID)
            {
                res = -1;
                Debug.Assert(cur.RootID == 0 || cur.Pages[cur.ID].Cells == 0);
                return RC.OK;
            }
            Debug.Assert(cur.Pages[0].IntKey || idxKey != null);
            int c;
            for (; ; )
            {
                // pPage->nCell must be greater than zero. If this is the root-page the cursor would have been INVALID above and this for(;;) loop
                // not run. If this is not the root-page, then the moveToChild() routine would have already detected db corruption. Similarly, pPage must
                // be the right kind (index or table) of b-tree page. Otherwise a moveToChild() or moveToRoot() call would have detected corruption.
                MemPage page = cur.Pages[cur.ID];
                Debug.Assert(page.Cells > 0);
                Debug.Assert(page.IntKey == (idxKey == null));
                uint idx;
                uint lwr = 0;
                uint upr = (uint)(page.Cells - 1);
                if (biasRight != 0)
                    cur.Idxs[cur.ID] = (ushort)(idx = upr);
                else
                    cur.Idxs[cur.ID] = (ushort)(idx = (upr + lwr) / 2);
                for (; ; )
                {
                    Debug.Assert(idx == cur.Idxs[cur.ID]);
                    cur.Info.Size = 0;
                    uint cell_ = findCell(page, idx) + page.ChildPtrSize; // Pointer to current cell in pPage
                    if (page.IntKey)
                    {
                        if (page.HasData)
                        {
                            uint dummy = 0;
                            cell_ += ConvertEx.GetVarint32(page.Data, cell_, out dummy);
                        }
                        long cellKeyLength = 0;
                        ConvertEx.GetVarint(page.Data, cell_, out cellKeyLength);
                        if (cellKeyLength == intKey)
                            c = 0;
                        else if (cellKeyLength < intKey)
                            c = -1;
                        else
                            c = +1;
                        cur.ValidNKey = true;
                        cur.Info.Key = cellKeyLength;
                    }
                    else
                    {
                        // The maximum supported page-size is 65536 bytes. This means that the maximum number of record bytes stored on an index B-Tree
                        // page is less than 16384 bytes and may be stored as a 2-byte varint. This information is used to attempt to avoid parsing 
                        // the entire cell by checking for the cases where the record is stored entirely within the b-tree page by inspecting the first 
                        // 2 bytes of the cell.
                        int cellLength = page.Data[cell_ + 0];
                        if (cellLength <= page.Max1bytePayload)
                        {
                            // This branch runs if the record-size field of the cell is a single byte varint and the record fits entirely on the main b-tree page.
                            c = _vdbe.RecordCompare(cellLength, page.Data, cell_ + 1, idxKey);
                        }
                        else if ((page.Data[cell_ + 1] & 0x80) == 0 && (cellLength = ((cellLength & 0x7f) << 7) + page.Data[cell_ + 1]) <= page.MaxLocal)
                        {
                            // The record-size field is a 2 byte varint and the record fits entirely on the main b-tree page.
                            c = _vdbe.RecordCompare(cellLength, page.Data, cell_ + 2, idxKey);
                        }
                        else
                        {
                            // The record flows over onto one or more overflow pages. In this case the whole cell needs to be parsed, a buffer allocated
                            // and accessPayload() used to retrieve the record into the buffer before VdbeRecordCompare() can be called.
                            var cellBody = new byte[page.Data.Length - cell_ + page.ChildPtrSize];
                            Buffer.BlockCopy(page.Data, (int)cell_ - page.ChildPtrSize, cellBody, 0, cellBody.Length);
                            btreeParseCellPtr(page, cellBody, ref cur.Info);
                            cellLength = (int)cur.Info.Key;
                            var cellKey = C._alloc(cellLength);
//.........这里部分代码省略.........
开发者ID:BclEx,项目名称:GpuStructs,代码行数:101,代码来源:Btree.cs


示例13: Last

        public static RC Last(BtCursor cur, ref int res)
        {
            Debug.Assert(cursorHoldsMutex(cur));
            Debug.Assert(MutexEx.Held(cur.Btree.Ctx.Mutex));

            // If the cursor already points to the last entry, this is a no-op.
            if (cur.State == CURSOR.VALID && cur.AtLast != 0)
            {
#if DEBUG
                // This block serves to Debug.Assert() that the cursor really does point to the last entry in the b-tree.
                for (var ii = 0; ii < cur.ID; ii++)
                    Debug.Assert(cur.Idxs[ii] == cur.Pages[ii].Cells);
                Debug.Assert(cur.Idxs[cur.ID] == cur.Pages[cur.ID].Cells - 1);
                Debug.Assert(cur.Pages[cur.ID].Leaf);
#endif
                return RC.OK;
            }

            var rc = moveToRoot(cur);
            if (rc == RC.OK)
            {
                if (cur.State == CURSOR.INVALID)
                {
                    Debug.Assert(cur.Pages[cur.ID].Cells == 0);
                    res = 1;
                }
                else
                {
                    Debug.Assert(cur.State == CURSOR.VALID);
                    res = 0;
                    rc = moveToRightmost(cur);
                    cur.AtLast = (byte)(rc == RC.OK ? 1 : 0);
                }
            }
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:36,代码来源:Btree.cs


示例14: First

 public static RC First(BtCursor cur, ref int res)
 {
     Debug.Assert(cursorHoldsMutex(cur));
     Debug.Assert(MutexEx.Held(cur.Btree.Ctx.Mutex));
     var rc = moveToRoot(cur);
     if (rc == RC.OK)
     {
         if (cur.State == CURSOR.INVALID)
         {
             Debug.Assert(cur.Pages[cur.ID].Cells == 0);
             res = 1;
         }
         else
         {
             Debug.Assert(cur.Pages[cur.ID].Cells > 0);
             res = 0;
             rc = moveToLeftmost(cur);
         }
     }
     return rc;
 }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:21,代码来源:Btree.cs


示例15: balance

        static RC balance(BtCursor cur)
        {
#if DEBUG
            int balance_quick_called = 0;
            int balance_deeper_called = 0;
#else
            int balance_quick_called = 0;
            int balance_deeper_called = 0;
#endif

            byte[] free = null;
            int min = (int)cur.Bt.UsableSize * 2 / 3;
            RC rc = RC.OK;
            do
            {
                int pageID = cur.ID;
                MemPage page = cur.Pages[pageID];

                if (pageID == 0)
                {
                    if (page.Overflows != 0)
                    {
                        // The root page of the b-tree is overfull. In this case call the balance_deeper() function to create a new child for the root-page
                        // and copy the current contents of the root-page to it. The next iteration of the do-loop will balance the child page.
                        Debug.Assert(balance_deeper_called++ == 0);
                        rc = balance_deeper(page, ref cur.Pages[1]);
                        if (rc == RC.OK)
                        {
                            cur.ID = 1;
                            cur.Idxs[0] = 0;
                            cur.Idxs[1] = 0;
                            Debug.Assert(cur.Pages[1].Overflows != 0);
                        }
                    }
                    else
                        break;
                }
                else if (page.Overflows == 0 && page.Frees <= min)
                    break;
                else
                {
                    MemPage parent = cur.Pages[pageID - 1];
                    ushort idx = cur.Idxs[pageID - 1];

                    rc = Pager.Write(parent.DBPage);
                    if (rc == RC.OK)
                    {
#if !OMIT_QUICKBALANCE
                        if (page.HasData && page.Overflows == 1 && page.OvflIdxs[0] == page.Cells && parent.ID != 1 && parent.Cells == idx)
                        {
                            // Call balance_quick() to create a new sibling of pPage on which to store the overflow cell. balance_quick() inserts a new cell
                            // into pParent, which may cause pParent overflow. If this happens, the next interation of the do-loop will balance pParent 
                            // use either balance_nonroot() or balance_deeper(). Until this happens, the overflow cell is stored in the aBalanceQuickSpace[] buffer. 
                            //
                            // The purpose of the following assert() is to check that only a single call to balance_quick() is made for each call to this
                            // function. If this were not verified, a subtle bug involving reuse of the aBalanceQuickSpace[] might sneak in.
                            Debug.Assert((balance_quick_called++) == 0);
                            rc = balance_quick(parent, page, _balanceQuickSpace);
                        }
                        else
#endif
                        {
                            // In this case, call balance_nonroot() to redistribute cells between pPage and up to 2 of its sibling pages. This involves
                            // modifying the contents of pParent, which may cause pParent to become overfull or underfull. The next iteration of the do-loop
                            // will balance the parent page to correct this.
                            // 
                            // If the parent page becomes overfull, the overflow cell or cells are stored in the pSpace buffer allocated immediately below. 
                            // A subsequent iteration of the do-loop will deal with this by calling balance_nonroot() (balance_deeper() may be called first,
                            // but it doesn't deal with overflow cells - just moves them to a different page). Once this subsequent call to balance_nonroot() 
                            // has completed, it is safe to release the pSpace buffer used by the previous call, as the overflow cell data will have been 
                            // copied either into the body of a database page or into the new pSpace buffer passed to the latter call to balance_nonroot().
                            byte[] space = null; //PCache.PageAlloc2((int)cur.Bt.PageSize);
                            rc = balance_nonroot(parent, idx, space, pageID == 1, cur.Hints != 0);
                            if (free != null)
                            {
                                // If pFree is not NULL, it points to the pSpace buffer used  by a previous call to balance_nonroot(). Its contents are
                                // now stored either on real database pages or within the new pSpace buffer, so it may be safely freed here.
                                PCache.PageFree2(ref free);
                            }

                            // The pSpace buffer will be freed after the next call to balance_nonroot(), or just before this function returns, whichever comes first.
                            free = space;
                        }
                    }

                    page.Overflows = 0;

                    // The next iteration of the do-loop balances the parent page.
                    releasePage(page);
                    cur.ID--;
                }
            } while (rc == RC.OK);

            if (free != null)
                PCache.PageFree2(ref free);
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:97,代码来源:Btree.cs


示例16: Insert

        public static RC Insert(BtCursor cur, byte[] key, long keyLength, byte[] data, int dataLength, int zero, int appendBias, int seekResult)
        {
            if (cur.State == CURSOR.FAULT)
            {
                Debug.Assert(cur.SkipNext != 0);
                return (RC)cur.SkipNext;
            }

            Btree p = cur.Btree;
            BtShared bt = p.Bt;
            Debug.Assert(cursorHoldsMutex(cur));
            Debug.Assert(cur.WrFlag && bt.InTransaction == TRANS.WRITE && (bt.BtsFlags & BTS.READ_ONLY) == 0);
            Debug.Assert(hasSharedCacheTableLock(p, cur.RootID, cur.KeyInfo != null, LOCK.WRITE));

            // Assert that the caller has been consistent. If this cursor was opened expecting an index b-tree, then the caller should be inserting blob
            // keys with no associated data. If the cursor was opened expecting an intkey table, the caller should be inserting integer keys with a
            // blob of associated data.
            Debug.Assert((key == null) == (cur.KeyInfo == null));

            // Save the positions of any other cursors open on this table.
            //
            // In some cases, the call to btreeMoveto() below is a no-op. For example, when inserting data into a table with auto-generated integer
            // keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the integer key to use. It then calls this function to actually insert the 
            // data into the intkey B-Tree. In this case btreeMoveto() recognizes that the cursor is already where it needs to be and returns without
            // doing any work. To avoid thwarting these optimizations, it is important not to clear the cursor here.
            RC rc = saveAllCursors(bt, cur.RootID, cur);
            if (rc != RC.OK) return rc;

            // If this is an insert into a table b-tree, invalidate any incrblob cursors open on the row being replaced (assuming this is a replace
            // operation - if it is not, the following is a no-op).
            if (cur.KeyInfo == null)
                invalidateIncrblobCursors(p, keyLength, false);

            int loc = seekResult; // -1: before desired location  +1: after
            if (loc == 0)
            {
                rc = btreeMoveto(cur, key, keyLength, appendBias, ref loc);
                if (rc != RC.OK) return rc;
            }
            Debug.Assert(cur.State == CURSOR.VALID || (cur.State == CURSOR.INVALID && loc != 0));

            MemPage page = cur.Pages[cur.ID];
            Debug.Assert(page.IntKey || keyLength >= 0);
            Debug.Assert(page.Leaf || !page.IntKey);

            TRACE("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", cur.RootID, keyLength, dataLength, page.ID, loc == 0 ? "overwrite" : "new entry");
            Debug.Assert(page.IsInit);
            allocateTempSpace(bt);
            byte[] newCell = bt.TmpSpace;
            if (newCell == null) return RC.NOMEM;
            ushort sizeNew = 0;
            rc = fillInCell(page, newCell, key, keyLength, data, dataLength, zero, ref sizeNew);
            if (rc != RC.OK) goto end_insert;
            Debug.Assert(sizeNew == cellSizePtr(page, newCell));
            Debug.Assert(sizeNew <= MX_CELL_SIZE(bt));
            uint idx = cur.Idxs[cur.ID];
            if (loc == 0)
            {
                Debug.Assert(idx < page.Cells);
                rc = Pager.Write(page.DBPage);
                if (rc != RC.OK)
                    goto end_insert;
                uint oldCell_ = findCell(page, idx);
                if (!page.Leaf)
                {
                    //_memcpy(newCell, oldCell, 4);
                    newCell[0] = page.Data[oldCell_ + 0];
                    newCell[1] = page.Data[oldCell_ + 1];
                    newCell[2] = page.Data[oldCell_ + 2];
                    newCell[3] = page.Data[oldCell_ + 3];
                }
                ushort sizeOld = cellSizePtr(page, oldCell_);
                rc = clearCell(page, oldCell_);
                dropCell(page, idx, sizeOld, ref rc);
                if (rc != RC.OK) goto end_insert;
            }
            else if (loc < 0 && page.Cells > 0)
            {
                Debug.Assert(page.Leaf);
                idx = ++cur.Idxs[cur.ID];
            }
            else
                Debug.Assert(page.Leaf);
            insertCell(page, idx, newCell, sizeNew, null, 0, ref rc);
            Debug.Assert(rc != RC.OK || page.Cells > 0 || page.Overflows > 0);

            // If no error has occurred and pPage has an overflow cell, call balance() to redistribute the cells within the tree. Since balance() may move
            // the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey variables.
            //
            // Previous versions of SQLite called moveToRoot() to move the cursor back to the root page as balance() used to invalidate the contents
            // of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, set the cursor state to "invalid". This makes common insert operations
            // slightly faster.
            //
            // There is a subtle but important optimization here too. When inserting multiple records into an intkey b-tree using a single cursor (as can
            // happen while processing an "INSERT INTO ... SELECT" statement), it is advantageous to leave the cursor pointing to the last entry in
            // the b-tree if possible. If the cursor is left pointing to the last entry in the table, and the next row inserted has an integer key
            // larger than the largest existing key, it is possible to insert the row without seeking the cursor. This can be a big performance boost.
            cur.Info.Size = 0;
            cur.ValidNKey = false;
            if (rc == RC.OK && page.Overflows != 0)
//.........这里部分代码省略.........
开发者ID:BclEx,项目名称:GpuStructs,代码行数:101,代码来源:Btree.cs


示例17: Previous

        public static RC Previous(BtCursor cur, ref int res)
        {
            Debug.Assert(cursorHoldsMutex(cur));
            var rc = restoreCursorPosition(cur);
            if (rc != RC.OK)
                return rc;
            cur.AtLast = 0;
            if (cur.State == CURSOR.INVALID)
            {
                res = 1;
                return RC.OK;
            }
            if (cur.SkipNext < 0)
            {
                cur.SkipNext = 0;
                res = 0;
                return RC.OK;
            }
            cur.SkipNext = 0;

            MemPage page = cur.Pages[cur.ID];
            Debug.Assert(page.IsInit);
            if (!page.Leaf)
            {
                uint idx = cur.Idxs[cur.ID];
                rc = moveToChild(cur, ConvertEx.Get4(page.Data, findCell(page, idx)));
                if (rc != RC.OK)
                    return rc;
                rc = moveToRightmost(cur);
            }
            else
            {
                while (cur.Idxs[cur.ID] == 0)
                {
                    if (cur.ID == 0)
                    {
                        cur.State = CURSOR.INVALID;
                        res = 1;
                        return RC.OK;
                    }
                    moveToParent(cur);
                }
                cur.Info.Size = 0;
                cur.ValidNKey = false;

                cur.Idxs[cur.ID]--;
                page = cur.Pages[cur.ID];
                if (page.IntKey && !page.Leaf)
                    rc = Previous(cur, ref res);
                else
                    rc = RC.OK;
            }
            res = 0;
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:55,代码来源:Btree.cs


示例18: Count

        public static RC Count(BtCursor cur, ref long entrysRef)
        {
            if (cur.RootID == 0)
            {
                entrysRef = 0;
                return RC.OK;
            }
            var rc = moveToRoot(cur);

            // Unless an error occurs, the following loop runs one iteration for each page in the B-Tree structure (not including overflow pages).
            long entrys = 0; // Value to return in pnEntry
            while (rc == RC.OK)
            {
                // If this is a leaf page or the tree is not an int-key tree, then this page contains countable entries. Increment the entry counter accordingly.
                MemPage page = cur.Pages[cur.ID]; // Current page of the b-tree
                if (page.Leaf || !page.IntKey)
                    entrys += page.Cells;

                // pPage is a leaf node. This loop navigates the cursor so that it points to the first interior cell that it points to the parent of
                // the next page in the tree that has not yet been visited. The pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell
                // of the page, or to the number of cells in the page if the next page to visit is the right-child of its parent.
                //
                // If all pages in the tree have been visited, return SQLITE_OK to the caller.
                if (page.Leaf)
                {
                    do
                    {
                        if (cur.ID == 0)
                        {
                            // All pages of the b-tree have been visited. Return successfully.
                            entrysRef = entrys;
                            return RC.OK;
                        }
                        moveToParent(cur);
                    } while (cur.Idxs[cur.ID] >= cur.Pages[cur.ID].Cells);

                    cur.Idxs[cur.ID]++;
                    page = cur.Pages[cur.ID];
                }

                // Descend to the child node of the cell that the cursor currently points at. This is the right-child if (iIdx==pPage->nCell).
                uint idx = cur.Idxs[cur.ID]; // Index of child node in parent
                if (idx == page.Cells)
                    rc = moveToChild(cur, ConvertEx.Get4(page.Data, page.HdrOffset + 8));
                else
                    rc = moveToChild(cur, ConvertEx.Get4(page.Data, findCell(page, idx)));
            }

            // An error has occurred. Return an error code.
            return rc;
        }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:51,代码来源:Btree.cs


示例19: saveAllCursors

 static RC saveAllCursors(BtShared bt, Pid root, BtCursor except)
 {
     Debug.Assert(MutexEx.Held(bt.Mutex));
     Debug.Assert(except == null || except.Bt == bt);
     for (var p = bt.Cursor; p != null; p = p.Next)
     {
         if (p != except && (root == 0 || p.RootID == root) && p.State == CURSOR.VALID)
         {
             var rc = saveCursorPosition(p);
             if (rc != RC.OK)
                 return rc;
         }
     }
     return RC.OK;
 }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:15,代码来源:Btree.cs


示例20: CacheOverflow

该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# BtShared类代码示例发布时间:2022-05-24
下一篇:
C# BsonWriter类代码示例发布时间:2022-05-24
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap