static VdbeCursor AllocateCursor(Vdbe p, int curID, int fields, int db, bool isBtreeCursor) { // Find the memory cell that will be used to store the blob of memory required for this VdbeCursor structure. It is convenient to use a // vdbe memory cell to manage the memory allocation required for a VdbeCursor structure for the following reasons: // // * Sometimes cursor numbers are used for a couple of different purposes in a vdbe program. The different uses might require // different sized allocations. Memory cells provide growable allocations. // // * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can be freed lazily via the sqlite3_release_memory() API. This // minimizes the number of malloc calls made by the system. // // Memory cells for cursors are allocated at the top of the address space. Memory cell (p->nMem) corresponds to cursor 0. Space for // cursor 1 is managed by memory cell (p->nMem-1), etc. VdbeCursor cx = null; Debug.Assert(curID < p.Cursors.length); if (p.Cursors[curID] != null) { p.FreeCursor(p.Cursors[curID]); p.Cursors[curID] = null; } //: if (Vdbe.MemGrow(mem, bytes, false) == RC.OK) { p.Cursors[curID] = cx = new VdbeCursor(); cx.Db = db; cx.Fields = fields; if (fields != 0) cx.Types = new uint[fields]; if (isBtreeCursor) { cx.Cursor = sqlite3MemMallocBtCursor(cx.Cursor); Btree.CursorZero(cx.Cursor); } } return cx; }
static void CloseAllCursors(Vdbe p) { if (p.Frames.data != null) { VdbeFrame frame; for (frame = p.Frames.data; frame.Parent != null; frame = frame.Parent) { } FrameRestore(frame); } p.Frames.data = null; p.Frames.length = 0; if (p.Cursors.data != null) { int i; for (i = 0; i < p.Cursors.length; i++) { VdbeCursor cur = p.Cursors[i]; if (cur != null) { p.FreeCursor(cur); p.Cursors[i] = null; } } } if (p.Mems.data != null) ReleaseMemArray(p.Mems.data, 1, p.Mems.length); while (p.DelFrames != null) { VdbeFrame del = p.DelFrames; p.DelFrames = del.Parent; FrameDelete(del); } }