本文整理汇总了C#中MemPage类的典型用法代码示例。如果您正苦于以下问题:C# MemPage类的具体用法?C# MemPage怎么用?C# MemPage使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
MemPage类属于命名空间,在下文中一共展示了MemPage类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: decodeFlags
static RC decodeFlags(MemPage page, int flagByte)
{
Debug.Assert(page.HdrOffset == (page.ID == 1 ? 100 : 0));
Debug.Assert(MutexEx.Held(page.Bt.Mutex));
page.Leaf = ((flagByte >> 3) != 0); Debug.Assert(PTF_LEAF == 1 << 3);
flagByte &= ~PTF_LEAF;
page.ChildPtrSize = (byte)(page.Leaf ? 0 : 4);
BtShared bt = page.Bt; // A copy of pPage.pBt
if (flagByte == (PTF_LEAFDATA | PTF_INTKEY))
{
page.IntKey = true;
page.HasData = page.Leaf;
page.MaxLocal = bt.MaxLeaf;
page.MinLocal = bt.MinLeaf;
}
else if (flagByte == PTF_ZERODATA)
{
page.IntKey = false;
page.HasData = false;
page.MaxLocal = bt.MaxLocal;
page.MinLocal = bt.MinLocal;
}
else
return SysEx.CORRUPT_BKPT();
page.Max1bytePayload = bt.Max1bytePayload;
return RC.OK;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:27,代码来源:Btree.cs
示例2: freeSpace
static RC freeSpace(MemPage page, uint start, int size) { return freeSpace(page, (int)start, size); }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:1,代码来源:Btree.cs
示例3: defragmentPage
static RC defragmentPage(MemPage page)
{
Debug.Assert(Pager.Iswriteable(page.DBPage));
Debug.Assert(page.Bt != null);
Debug.Assert(page.Bt.UsableSize <= Pager.MAX_PAGE_SIZE);
Debug.Assert(page.Overflows == 0);
Debug.Assert(MutexEx.Held(page.Bt.Mutex));
byte[] temp = page.Bt.Pager.get_TempSpace(); // Temp area for cell content
byte[] data = page.Data; // The page data
int hdr = page.HdrOffset; // Offset to the page header
int cellOffset = page.CellOffset; // Offset to the cell pointer array
int cells = page.Cells; // Number of cells on the page
Debug.Assert(cells == ConvertEx.Get2(data, hdr + 3));
uint usableSize = page.Bt.UsableSize; // Number of usable bytes on a page
uint cbrk = (uint)ConvertEx.Get2(data, hdr + 5); // Offset to the cell content area
Buffer.BlockCopy(data, (int)cbrk, temp, (int)cbrk, (int)(usableSize - cbrk)); // memcpy(temp[cbrk], ref data[cbrk], usableSize - cbrk);
cbrk = usableSize;
ushort cellFirst = (ushort)(cellOffset + 2 * cells); // First allowable cell index
ushort cellLast = (ushort)(usableSize - 4); // Last possible cell index
var addr = 0; // The i-th cell pointer
for (var i = 0; i < cells; i++)
{
addr = cellOffset + i * 2;
uint pc = ConvertEx.Get2(data, addr); // Address of a i-th cell
#if !ENABLE_OVERSIZE_CELL_CHECK
// These conditions have already been verified in btreeInitPage() if ENABLE_OVERSIZE_CELL_CHECK is defined
if (pc < cellFirst || pc > cellLast)
return SysEx.CORRUPT_BKPT();
#endif
Debug.Assert(pc >= cellFirst && pc <= cellLast);
uint size = cellSizePtr(page, temp, pc); // Size of a cell
cbrk -= size;
#if ENABLE_OVERSIZE_CELL_CHECK
if (cbrk < cellFirst || pc + size > usableSize)
return SysEx.CORRUPT_BKPT();
#else
if (cbrk < cellFirst || pc + size > usableSize)
return SysEx.CORRUPT_BKPT();
#endif
Debug.Assert(cbrk + size <= usableSize && cbrk >= cellFirst);
Buffer.BlockCopy(temp, (int)pc, data, (int)cbrk, (int)size);
ConvertEx.Put2(data, addr, cbrk);
}
Debug.Assert(cbrk >= cellFirst);
ConvertEx.Put2(data, hdr + 5, cbrk);
data[hdr + 1] = 0;
data[hdr + 2] = 0;
data[hdr + 7] = 0;
addr = cellOffset + 2 * cells;
Array.Clear(data, addr, (int)(cbrk - addr));
Debug.Assert(Pager.Iswriteable(page.DBPage));
if (cbrk - cellFirst != page.Frees)
return SysEx.CORRUPT_BKPT();
return RC.OK;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:55,代码来源:Btree.cs
示例4: cellSize
static ushort cellSize(MemPage page, int cell) { return -1; }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:1,代码来源:Btree.cs
示例5: cellSizePtr
static ushort cellSizePtr(MemPage page, byte[] cell)
{
#if DEBUG
// The value returned by this function should always be the same as the (CellInfo.nSize) value found by doing a full parse of the
// cell. If SQLITE_DEBUG is defined, an assert() at the bottom of this function verifies that this invariant is not violated.
var debuginfo = new CellInfo();
btreeParseCellPtr(page, cell, ref debuginfo);
#else
var debuginfo = new CellInfo();
#endif
var iter = page.ChildPtrSize;
uint size = 0;
if (page.IntKey)
{
if (page.HasData)
iter += ConvertEx.GetVarint32(cell, out size); // iter += ConvertEx.GetVarint32(iter, out size);
else
size = 0;
// pIter now points at the 64-bit integer key value, a variable length integer. The following block moves pIter to point at the first byte
// past the end of the key value.
int end = iter + 9; // end = &pIter[9];
while (((cell[iter++]) & 0x80) != 0 && iter < end) { } // while ((iter++) & 0x80 && iter < end);
}
else
iter += ConvertEx.GetVarint32(cell, iter, out size); //pIter += getVarint32( pIter, out nSize );
if (size > page.MaxLocal)
{
int minLocal = page.MinLocal;
size = (uint)(minLocal + (size - minLocal) % (page.Bt.UsableSize - 4));
if (size > page.MaxLocal)
size = (uint)minLocal;
size += 4;
}
size += (uint)iter; // size += (uint32)(iter - cell);
// The minimum size of any cell is 4 bytes.
if (size < 4)
size = 4;
Debug.Assert(size == debuginfo.Size);
return (ushort)size;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:44,代码来源:Btree.cs
示例6: findCell
//#define ptrmapPut(w,x,y,z,rc)
//#define ptrmapGet(w,x,y,z) RC.OK
//#define ptrmapPutOvflPtr(x, y, rc)
#endif
static uint findCell(MemPage page, uint cell) { return ConvertEx.Get2(page.Data, page.CellOffset + 2 * cell); }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:6,代码来源:Btree.cs
示例7: btreeCreateTable
static RC btreeCreateTable(Btree p, ref int tableID, int createTabFlags)
{
BtShared bt = p.Bt;
Debug.Assert(p.HoldsMutex());
Debug.Assert(bt.InTransaction == TRANS.WRITE);
Debug.Assert((bt.BtsFlags & BTS.READ_ONLY) == 0);
RC rc;
MemPage root = new MemPage();
Pid rootID = 0;
#if OMIT_AUTOVACUUM
rc = allocateBtreePage(bt, ref root, ref rootID, 1, BTALLOC.ANY);
if (rc != RC.OK)
return rc;
#else
if (bt.AutoVacuum)
{
// Creating a new table may probably require moving an existing database to make room for the new tables root page. In case this page turns
// out to be an overflow page, delete all overflow page-map caches held by open cursors.
invalidateAllOverflowCache(bt);
// Read the value of meta[3] from the database to determine where the root page of the new table should go. meta[3] is the largest root-page
// created so far, so the new root-page is (meta[3]+1).
p.GetMeta(META.LARGEST_ROOT_PAGE, ref rootID);
rootID++;
// The new root-page may not be allocated on a pointer-map page, or the PENDING_BYTE page.
while (rootID == PTRMAP_PAGENO(bt, rootID) || rootID == PENDING_BYTE_PAGE(bt))
rootID++;
Debug.Assert(rootID >= 3);
// Allocate a page. The page that currently resides at pgnoRoot will be moved to the allocated page (unless the allocated page happens
// to reside at pgnoRoot).
Pid moveID = 0; // Move a page here to make room for the root-page
MemPage pageMove = new MemPage(); // The page to move to.
rc = allocateBtreePage(bt, ref pageMove, ref moveID, rootID, BTALLOC.EXACT);
if (rc != RC.OK)
return rc;
if (moveID != rootID)
{
releasePage(pageMove);
// Move the page currently at pgnoRoot to pgnoMove.
rc = btreeGetPage(bt, rootID, ref root, false);
if (rc != RC.OK)
return rc;
// pgnoRoot is the page that will be used for the root-page of the new table (assuming an error did not occur). But we were
// allocated pgnoMove. If required (i.e. if it was not allocated by extending the file), the current page at position pgnoMove
// is already journaled.
PTRMAP type = 0;
Pid ptrPageID = 0;
rc = ptrmapGet(bt, rootID, ref type, ref ptrPageID);
if (type == PTRMAP.ROOTPAGE || type == PTRMAP.FREEPAGE)
rc = SysEx.CORRUPT_BKPT();
if (rc != RC.OK)
{
releasePage(root);
return rc;
}
Debug.Assert(type != PTRMAP.ROOTPAGE);
Debug.Assert(type != PTRMAP.FREEPAGE);
rc = relocatePage(bt, root, type, ptrPageID, moveID, false);
releasePage(root);
// Obtain the page at pgnoRoot
if (rc != RC.OK)
return rc;
rc = btreeGetPage(bt, rootID, ref root, false);
if (rc != RC.OK)
return rc;
rc = Pager.Write(root.DBPage);
if (rc != RC.OK)
{
releasePage(root);
return rc;
}
}
else
root = pageMove;
// Update the 0pointer-map and meta-data with the new root-page number.
ptrmapPut(bt, rootID, PTRMAP.ROOTPAGE, 0, ref rc);
if (rc != RC.OK)
{
releasePage(root);
return rc;
}
// When the new root page was allocated, page 1 was made writable in order either to increase the database filesize, or to decrement the
// freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail.
Debug.Assert(Pager.Iswriteable(bt.Page1.DBPage));
rc = p.UpdateMeta(META.LARGEST_ROOT_PAGE, rootID);
if (C._NEVER(rc != RC.OK))
{
releasePage(root);
return rc;
}
}
//.........这里部分代码省略.........
开发者ID:BclEx,项目名称:GpuStructs,代码行数:101,代码来源:Btree.cs
示例8: balance_deeper
static RC balance_deeper(MemPage root, ref MemPage childOut)
{
var bt = root.Bt; // The BTree
Debug.Assert(root.Overflows > 0);
Debug.Assert(MutexEx.Held(bt.Mutex));
// Make pRoot, the root page of the b-tree, writable. Allocate a new page that will become the new right-child of pPage. Copy the contents
// of the node stored on pRoot into the new child page.
MemPage child = null; // Pointer to a new child page
Pid childID = 0; // Page number of the new child page
var rc = Pager.Write(root.DBPage);
if (rc == RC.OK)
{
rc = allocateBtreePage(bt, ref child, ref childID, root.ID, BTALLOC.ANY);
copyNodeContent(root, child, ref rc);
#if !OMIT_AUTOVACUUM
if (bt.AutoVacuum)
ptrmapPut(bt, childID, PTRMAP.BTREE, root.ID, ref rc);
#endif
}
if (rc != RC.OK)
{
childOut = null;
releasePage(child);
return rc;
}
Debug.Assert(Pager.Iswriteable(child.DBPage));
Debug.Assert(Pager.Iswriteable(root.DBPage));
Debug.Assert(child.Cells == root.Cells);
TRACE("BALANCE: copy root %d into %d\n", root.ID, child.ID);
// Copy the overflow cells from pRoot to pChild
Array.Copy(root.OvflIdxs, child.OvflIdxs, root.Overflows);
Array.Copy(root.Ovfls, child.Ovfls, root.Overflows);
child.Overflows = root.Overflows;
// Zero the contents of pRoot. Then install pChild as the right-child.
zeroPage(root, child.Data[0] & ~PTF_LEAF);
ConvertEx.Put4(root.Data, root.HdrOffset + 8, childID);
childOut = child;
return RC.OK;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:45,代码来源:Btree.cs
示例9: balance_nonroot
// under C#; Try to reuse Memory
static RC balance_nonroot(MemPage parent, uint parentIdx, byte[] ovflSpace, bool isRoot, bool bulk)
{
BtShared bt = parent.Bt; // The whole database
Debug.Assert(MutexEx.Held(bt.Mutex));
Debug.Assert(Pager.Iswriteable(parent.DBPage));
#if false
TRACE("BALANCE: begin page %d child of %d\n", page.ID, parent.ID);
#endif
// At this point pParent may have at most one overflow cell. And if this overflow cell is present, it must be the cell with
// index iParentIdx. This scenario comes about when this function is called (indirectly) from sqlite3BtreeDelete().
Debug.Assert(parent.Overflows == 0 || parent.Overflows == 1);
Debug.Assert(parent.Overflows == 0 || parent.OvflIdxs[0] == parentIdx);
if (ovflSpace == null)
return RC.NOMEM;
// Find the sibling pages to balance. Also locate the cells in pParent that divide the siblings. An attempt is made to find NN siblings on
// either side of pPage. More siblings are taken from one side, however, if there are fewer than NN siblings on the other side. If pParent
// has NB or fewer children then all children of pParent are taken.
//
// This loop also drops the divider cells from the parent page. This way, the remainder of the function does not have to deal with any
// overflow cells in the parent page, since if any existed they will have already been removed.
uint i = (uint)parent.Overflows + parent.Cells;
uint nxDiv; // Next divider slot in pParent.aCell[]
if (i < 2)
nxDiv = 0;
else
{
if (parentIdx == 0)
nxDiv = 0;
else if (parentIdx == i)
nxDiv = i - 2 + (bulk ? 1U : 0U);
else
{
Debug.Assert(!bulk);
nxDiv = parentIdx - 1;
}
i = 2 - (bulk ? 1U : 0U);
}
uint right_; // Location in parent of right-sibling pointer
if ((i + nxDiv - parent.Overflows) == parent.Cells)
right_ = parent.HdrOffset + 8U;
else
right_ = findCell(parent, i + nxDiv - parent.Overflows);
Pid id = ConvertEx.Get4(parent.Data, right_); // Temp var to store a page number in
RC rc;
MemPage[] oldPages = new MemPage[NB]; // pPage and up to two siblings
MemPage[] copyPages = new MemPage[NB]; // Private copies of apOld[] pages
MemPage[] newPages = new MemPage[NB + 2]; // pPage and up to NB siblings after balancing
uint oldPagesUsed = i + 1; // Number of pages in apOld[]
uint newPagesUsed = 0; // Number of pages in apNew[]
uint maxCells = 0; // Allocated size of apCell, szCell, aFrom.
uint[] divs_ = new uint[NB - 1]; // Divider cells in pParent
Pid[] countNew = new Pid[NB + 2]; // Index in aCell[] of cell after i-th page
ushort[] sizeNew = new ushort[NB + 2]; // Combined size of cells place on i-th page
byte[][] cell = null; // All cells begin balanced
while (true)
{
rc = getAndInitPage(bt, id, ref oldPages[i]);
if (rc != RC.OK)
{
//_memset(oldPages, 0, (i + 1) * sizeof(MemPage *));
goto balance_cleanup;
}
maxCells += 1U + oldPages[i].Cells + oldPages[i].Overflows;
if (i-- == 0) break;
if (i + nxDiv == parent.OvflIdxs[0] && parent.Overflows != 0)
{
divs_[i] = 0; //parent.Ovfls[0];
id = (Pid)ConvertEx.Get4(parent.Ovfls[0].Cell, divs_[i]);
sizeNew[i] = cellSizePtr(parent, divs_[i]);
parent.Overflows = 0;
}
else
{
divs_[i] = findCell(parent, i + nxDiv - parent.Overflows);
id = ConvertEx.Get4(parent.Data, divs_[i]);
sizeNew[i] = cellSizePtr(parent, divs_[i]);
// Drop the cell from the parent page. apDiv[i] still points to the cell within the parent, even though it has been dropped.
// This is safe because dropping a cell only overwrites the first four bytes of it, and this function does not need the first
// four bytes of the divider cell. So the pointer is safe to use later on.
//
// But not if we are in secure-delete mode. In secure-delete mode, the dropCell() routine will overwrite the entire cell with zeroes.
// In this case, temporarily copy the cell into the aOvflSpace[] buffer. It will be copied out again as soon as the aSpace[] buffer is allocated.
//if ((bt.BtsFlags & BTS.SECURE_DELETE) != 0)
//{
// int off = (int)(divs[i]) - (int)(parent.Data);
// if ((off + newPages[i]) > (int)bt.UsableSize)
// {
// rc = SysEx.CORRUPT_BKPT();
// Array.Clear(oldPages[0].Data, 0, oldPages[0].Data.Length);
// goto balance_cleanup;
// }
// else
// {
//.........这里部分代码省略.........
开发者ID:BclEx,项目名称:GpuStructs,代码行数:101,代码来源:Btree.cs
示例10: copyNodeContent
static void copyNodeContent(MemPage from, MemPage to, ref RC rcRef)
{
if (rcRef == RC.OK)
{
BtShared bt = from.Bt;
var fromData = from.Data;
var toData = to.Data;
int fromHdr = from.HdrOffset;
int toHdr = (to.ID == 1 ? 100 : 0);
Debug.Assert(from.IsInit);
Debug.Assert(from.Frees >= toHdr);
Debug.Assert(ConvertEx.Get2(fromData, fromHdr + 5) <= (int)bt.UsableSize);
// Copy the b-tree node content from page pFrom to page pTo.
int data = ConvertEx.Get2(fromData, fromHdr + 5);
Buffer.BlockCopy(fromData, data, toData, data, (int)bt.UsableSize - data);
Buffer.BlockCopy(fromData, fromHdr, toData, toHdr, from.CellOffset + 2 * from.Cells);
// Reinitialize page pTo so that the contents of the MemPage structure match the new data. The initialization of pTo can actually fail under
// fairly obscure circumstances, even though it is a copy of initialized page pFrom.
to.IsInit = false;
var rc = btreeInitPage(to);
if (rc != RC.OK)
{
rcRef = rc;
return;
}
// If this is an auto-vacuum database, update the pointer-map entries for any b-tree or overflow pages that pTo now contains the pointers to.
#if !OMIT_AUTOVACUUM
if (bt.AutoVacuum)
rcRef = setChildPtrmaps(to);
#endif
}
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:36,代码来源:Btree.cs
示例11: ptrmapCheckPages
static int ptrmapCheckPages(MemPage[] pageSet, int pages)
{
for (int i = 0; i < pages; i++)
{
MemPage page = pageSet[i];
BtShared bt = page.Bt;
Debug.Assert(page.IsInit);
Pid n;
PTRMAP e;
for (uint j = 0U; j < page.Cells; j++)
{
uint z_ = findCell(page, j);
CellInfo info = new CellInfo();
btreeParseCellPtr(page, z_, ref info);
if (info.Overflow != 0)
{
Pid ovfl = ConvertEx.Get4(page.Data, z_ + info.Overflow);
ptrmapGet(bt, ovfl, ref e, ref n);
Debug.Assert(n == page.ID && e == PTRMAP.OVERFLOW1);
}
if (!page.Leaf)
{
Pid child = ConvertEx.Get4(page.Data, z_);
ptrmapGet(bt, child, ref e, ref n);
Debug.Assert(n == page.ID && e == PTRMAP.BTREE);
}
}
if (!page.Leaf)
{
Pid child = ConvertEx.Get4(page.Data, page.HdrOffset + 8);
ptrmapGet(bt, child, ref e, ref n);
Debug.Assert(n == page.ID && e == PTRMAP.BTREE);
}
}
return 1;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:37,代码来源:Btree.cs
示例12: balance_quick
static int NB = (NN * 2 + 1); // Total pages involved in the balance
#if !OMIT_QUICKBALANCE
static RC balance_quick(MemPage parent, MemPage page, byte[] space)
{
BtShared bt = page.Bt; // B-Tree Database
Debug.Assert(MutexEx.Held(page.Bt.Mutex));
Debug.Assert(Pager.Iswriteable(parent.DBPage));
Debug.Assert(page.Overflows == 1);
// This error condition is now caught prior to reaching this function
if (page.Cells <= 0)
return SysEx.CORRUPT_BKPT();
// Allocate a new page. This page will become the right-sibling of pPage. Make the parent page writable, so that the new divider cell
// may be inserted. If both these operations are successful, proceed.
MemPage newPage = new MemPage(); // Newly allocated page
Pid newPageID = 0; // Page number of pNew
var rc = allocateBtreePage(bt, ref newPage, ref newPageID, 0, BTALLOC.ANY);
if (rc == RC.OK)
{
ushort out_ = 4; //byte[] out_ = &space[4];
byte[] cell = page.Ovfls[0].Cell;
ushort[] sizeCell = new ushort[1];
sizeCell[0] = cellSizePtr(page, cell);
Debug.Assert(Pager.Iswriteable(newPage.DBPage));
Debug.Assert(page.Data[0] == (PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF));
zeroPage(newPage, PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF);
assemblePage(newPage, 1, cell, sizeCell);
// If this is an auto-vacuum database, update the pointer map with entries for the new page, and any pointer from the
// cell on the page to an overflow page. If either of these operations fails, the return code is set, but the contents
// of the parent page are still manipulated by thh code below. That is Ok, at this point the parent page is guaranteed to
// be marked as dirty. Returning an error code will cause a rollback, undoing any changes made to the parent page.
#if !OMIT_AUTOVACUUM
if (bt.AutoVacuum)
{
ptrmapPut(bt, newPageID, PTRMAP.BTREE, parent.ID, ref rc);
if (sizeCell[0] > newPage.MinLocal)
ptrmapPutOvflPtr(newPage, cell, ref rc);
}
#endif
// Create a divider cell to insert into pParent. The divider cell consists of a 4-byte page number (the page number of pPage) and
// a variable length key value (which must be the same value as the largest key on pPage).
//
// To find the largest key value on pPage, first find the right-most cell on pPage. The first two fields of this cell are the
// record-length (a variable length integer at most 32-bits in size) and the key value (a variable length integer, may have any value).
// The first of the while(...) loops below skips over the record-length field. The second while(...) loop copies the key value from the
// cell on pPage into the pSpace buffer.
uint cell_ = findCell(page, page.Cells - 1U);
cell = page.Data;
uint stop = cell_ + 9;
while (((cell[cell_++]) & 0x80) != 0 && cell_ < stop) ;
stop = cell_ + 9;
while (((space[out_++] = cell[cell_++]) & 0x80) != 0 && cell_ < stop) ;
// Insert the new divider cell into pParent.
insertCell(parent, parent.Cells, space, out_, null, page.ID, ref rc);
// Set the right-child pointer of pParent to point to the new page.
ConvertEx.Put4(parent.Data, parent.HdrOffset + 8, newPageID);
// Release the reference to the new page.
releasePage(newPage);
}
return rc;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:73,代码来源:Btree.cs
示例13: parseCell
static void parseCell(MemPage page, uint cell_, ref CellInfo info) { btreeParseCellPtr(page, findCell(page, cell_), ref info); }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:1,代码来源:Btree.cs
示例14: btreeParseCell
static void btreeParseCell(MemPage page, uint cell, ref CellInfo info) { parseCell(page, cell, ref info); }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:1,代码来源:Btree.cs
示例15: findOverflowCell
static uint findOverflowCell(MemPage page, uint cell)
{
Debug.Assert(MutexEx.Held(page.Bt.Mutex));
for (var i = page.Overflows - 1; i >= 0; i--)
{
ushort k = page.OvflIdxs[i];
if (k <= cell)
{
if (k == cell)
return (uint)-i - 1; //page.Ovfls[i]; // Negative Offset means overflow cells
cell--;
}
}
return findCell(page, (uint)cell);
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:16,代码来源:Btree.cs
示例16: clearDatabasePage
static RC clearDatabasePage(BtShared bt, Pid id, bool freePageFlag, ref int changes)
{
Debug.Assert(MutexEx.Held(bt.Mutex));
if (id > btreePagecount(bt))
return SysEx.CORRUPT_BKPT();
MemPage page = new MemPage();
var rc = getAndInitPage(bt, id, ref page);
if (rc != RC.OK) return rc;
for (uint i = 0U; i < page.Cells; i++)
{
uint cell_ = findCell(page, i);
if (!page.Leaf)
{
rc = clearDatabasePage(bt, ConvertEx.Get4(page.Data, cell_), true, ref changes);
if (rc != RC.OK) goto cleardatabasepage_out;
}
rc = clearCell(page, cell_);
if (rc != RC.OK) goto cleardatabasepage_out;
}
if (!page.Leaf)
{
rc = clearDatabasePage(bt, ConvertEx.Get4(page.Data, 8), true, ref changes);
if (rc != RC.OK) goto cleardatabasepage_out;
}
else
{
Debug.Assert(page.IntKey);
changes += page.Cells;
}
if (freePageFlag)
freePage(page, ref rc);
else if ((rc = Pager.Write(page.DBPage)) == 0)
zeroPage(page, page.Data[0] | PTF_LEAF);
cleardatabasepage_out:
releasePage(page);
return rc;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:39,代码来源:Btree.cs
示例17: btreeDropTable
static RC btreeDropTable(Btree p, Pid tableID, ref int movedID)
{
BtShared bt = p.Bt;
Debug.Assert(p.HoldsMutex());
Debug.Assert(p.InTrans == TRANS.WRITE);
// It is illegal to drop a table if any cursors are open on the database. This is because in auto-vacuum mode the backend may
// need to move another root-page to fill a gap left by the deleted root page. If an open cursor was using this page a problem would occur.
//
// This error is caught long before control reaches this point.
if (C._NEVER(bt.Cursor != null))
{
BContext.ConnectionBlocked(p.Ctx, bt.Cursor.Btree.Ctx);
return RC.LOCKED_SHAREDCACHE;
}
MemPage page = null;
RC rc = btreeGetPage(bt, (Pid)tableID, ref page, false);
if (rc != RC.OK) return rc;
int dummy0 = 0;
rc = p.ClearTable((int)tableID, ref dummy0);
if (rc != RC.OK)
{
releasePage(page);
return rc;
}
movedID = 0;
if (tableID > 1)
{
#if OMIT_AUTOVACUUM
freePage(page, ref rc);
releasePage(page);
#else
if (bt.AutoVacuum)
{
Pid maxRootID = 0;
p.GetMeta(META.LARGEST_ROOT_PAGE, ref maxRootID);
if (tableID == maxRootID)
{
// If the table being dropped is the table with the largest root-page number in the database, put the root page on the free list.
freePage(page, ref rc);
releasePage(page);
if (rc != RC.OK)
return rc;
}
else
{
// The table being dropped does not have the largest root-page number in the database. So move the page that does into the
// gap left by the deleted root-page.
releasePage(page);
MemPage move = new MemPage();
rc = btreeGetPage(bt, maxRootID, ref move, false);
if (rc != RC.OK)
return rc;
rc = relocatePage(bt, move, PTRMAP.ROOTPAGE, 0, tableID, false);
releasePage(move);
if (rc != RC.OK)
return rc;
move = null;
rc = btreeGetPage(bt, maxRootID, ref move, false);
freePage(move, ref rc);
releasePage(move);
if (rc != RC.OK)
return rc;
movedID = (int)maxRootID;
}
// Set the new 'max-root-page' value in the database header. This is the old value less one, less one more if that happens to
// be a root-page number, less one again if that is the PENDING_BYTE_PAGE.
maxRootID--;
while (maxRootID == PENDING_BYTE_PAGE(bt) || PTRMAP_ISPAGE(bt, maxRootID))
maxRootID--;
Debug.Assert(maxRootID != PENDING_BYTE_PAGE(bt));
rc = p.UpdateMeta(META.LARGEST_ROOT_PAGE, maxRootID);
}
else
{
freePage(page, ref rc);
releasePage(page);
}
#endif
}
else
{
// If sqlite3BtreeDropTable was called on page 1. This really never should happen except in a corrupt database.
zeroPage(page, PTF_INTKEY | PTF_LEAF);
releasePage(page);
}
return rc;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:94,代码来源:Btree.cs
示例18: ptrmapPutOvflPtr
static void ptrmapPutOvflPtr(MemPage page, byte[] cell, ref RC rcRef)
{
if (rcRef != RC.OK) return;
Debug.Assert(cell != null);
var info = new CellInfo();
btreeParseCellPtr(page, cell, ref info);
Debug.Assert((info.Data + (page.IntKey ? 0 : info.Key)) == info.Payload);
if (info.Overflow != 0)
{
Pid ovfl = ConvertEx.Get4(cell, info.Overflow);
ptrmapPut(page.Bt, ovfl, PTRMAP.OVERFLOW1, page.ID, ref rcRef);
}
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:13,代码来源:Btree.cs
示例19: btreeParseCellPtr
static void btreeParseCellPtr(MemPage page, uint cellIdx, ref CellInfo info) { btreeParseCellPtr(page, page.Data, cellIdx, ref info); }
开发者ID:BclEx,项目名称:GpuStructs,代码行数:1,代码来源:Btree.cs
示例20: allocateSpace
static RC allocateSpace(MemPage page, int bytes, ref uint idx)
{
Debug.Assert(Pager.Iswriteable(page.DBPage));
Debug.Assert(page.Bt != null);
Debug.Assert(MutexEx.Held(page.Bt.Mutex));
Debug.Assert(bytes >= 0); // Minimum cell size is 4
Debug.Assert(page.Frees >= bytes);
Debug.Assert(page.Overflows == 0);
var usableSize = page.Bt.UsableSize; // Usable size of the page
Debug.Assert(bytes < usableSize - 8);
var hdr = page.HdrOffset; // Local cache of pPage.hdrOffset
var data = page.Data; // Local cache of pPage.aData
var frags = data[hdr + 7]; // Number of fragmented bytes on pPage
Debug.Assert(page.CellOffset == hdr + 12 - 4 * (page.Leaf ? 1 : 0));
var gap = page.CellOffset + 2 * page.Cells; // First byte of gap between cell pointers and cell content
var top = (uint)ConvertEx.Get2nz(data, hdr + 5); // First byte of cell content area
if (gap > top) return SysEx.CORRUPT_BKPT();
RC rc;
if (frags >= 60)
{
// Always defragment highly fragmented pages
rc = defragmentPage(page);
if (rc != RC.OK) return rc;
top = ConvertEx.Get2nz(data, hdr + 5);
}
else if (gap + 2 <= top)
{
// Search the freelist looking for a free slot big enough to satisfy the request. The allocation is made from the first free slot in
// the list that is large enough to accomadate it.
int pc;
for (int addr = hdr + 1; (pc = ConvertEx.Get2(data, addr)) > 0; addr = pc)
{
if (pc > usableSize - 4 || pc < addr + 4)
return SysEx.CORRUPT_BKPT();
int size = ConvertEx.Get2(data, pc + 2); // Size of free slot
if (size >= bytes)
{
int x = size - bytes;
if (x < 4)
{
// Remove the slot from the free-list. Update the number of fragmented bytes within the page.
data[addr + 0] = data[pc + 0]; // memcpy( data[addr], ref data[pc], 2 );
data[addr + 1] = data[pc + 1];
data[hdr + 7] = (byte)(frags + x);
}
else if (size + pc > usableSize)
return SysEx.CORRUPT_BKPT();
else // The slot remains on the free-list. Reduce its size to account for the portion used by the new allocation.
ConvertEx.Put2(data, pc + 2, x);
idx = (uint)(pc + x);
return RC.OK;
}
}
}
// Check to make sure there is enough space in the gap to satisfy the allocation. If not, defragment.
if (gap + 2 + bytes > top)
{
rc = defragmentPage(page);
if (rc != RC.OK) return rc;
top = ConvertEx.Get2nz(data, hdr + 5);
Debug.Assert(gap + bytes <= top);
}
// Allocate memory from the gap in between the cell pointer array and the cell content area. The btreeInitPage() call has already
// validated the freelist. Given that the freelist is valid, there is no way that the allocation can extend off the end of the page.
// The assert() below verifies the previous sentence.
top -= (uint)bytes;
ConvertEx.Put2(data, hdr + 5, top);
Debug.Assert(top + bytes <= (int)page.Bt.UsableSize);
idx = top;
return RC.OK;
}
开发者ID:BclEx,项目名称:GpuStructs,代码行数:75,代码来源:Btree.cs
注:本文中的MemPage类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论