Exemple #1
0
        internal RC decodeFlags(int flagByte)
        {
            Debug.Assert(this.HeaderOffset == (this.ID == 1 ? 100 : 0));
            Debug.Assert(MutexEx.Held(this.Shared.Mutex));
            this.Leaf = (byte)(flagByte >> 3);
            Debug.Assert(Btree.PTF_LEAF == 1 << 3);
            flagByte         &= ~Btree.PTF_LEAF;
            this.ChildPtrSize = (byte)(4 - 4 * this.Leaf);
            var pBt = this.Shared;

            if (flagByte == (Btree.PTF_LEAFDATA | Btree.PTF_INTKEY))
            {
                this.HasIntKey = true;
                this.HasData   = this.Leaf;
                this.MaxLocal  = pBt.MaxLeaf;
                this.MinLocal  = pBt.MinLeaf;
            }
            else if (flagByte == Btree.PTF_ZERODATA)
            {
                this.HasIntKey = false;
                this.HasData   = 0;
                this.MaxLocal  = pBt.MaxLocal;
                this.MinLocal  = pBt.MinLocal;
            }
            else
            {
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            return(RC.OK);
        }
        internal RC ptrmapGet(Pgno key, ref PTRMAP pEType, ref Pgno pPgno)
        {
            Debug.Assert(MutexEx.Held(this.Mutex));
            var iPtrmap = (int)MemPage.PTRMAP_PAGENO(this, key);
            var pDbPage = new PgHdr(); // The pointer map page
            var rc      = this.Pager.Get((Pgno)iPtrmap, ref pDbPage);

            if (rc != RC.OK)
            {
                return(rc);
            }
            var pPtrmap = Pager.sqlite3PagerGetData(pDbPage);// Pointer map page data
            var offset  = (int)MemPage.PTRMAP_PTROFFSET((Pgno)iPtrmap, key);

            if (offset < 0)
            {
                Pager.Unref(pDbPage);
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            Debug.Assert(offset <= (int)this.UsableSize - 5);
            var v = pPtrmap[offset];

            if (v < 1 || v > 5)
            {
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            pEType = (PTRMAP)v;
            pPgno  = ConvertEx.Get4(pPtrmap, offset + 1);
            Pager.Unref(pDbPage);
            return(RC.OK);
        }
        // was:moveToChild
        private RC MoveToChild(Pgno newID)
        {
            var id      = PageID;
            var newPage = new MemPage();

            Debug.Assert(HoldsMutex());
            Debug.Assert(State == CursorState.VALID);
            Debug.Assert(PageID < BTCURSOR_MAX_DEPTH);
            if (PageID >= (BTCURSOR_MAX_DEPTH - 1))
            {
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            var rc = Shared.getAndInitPage(newID, ref newPage);

            if (rc != RC.OK)
            {
                return(rc);
            }
            Pages[id + 1]       = newPage;
            PagesIndexs[id + 1] = 0;
            PageID++;
            Info.nSize = 0;
            ValidNKey  = false;
            if (newPage.Cells < 1 || newPage.HasIntKey != Pages[id].HasIntKey)
            {
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            return(RC.OK);
        }
Exemple #4
0
        public virtual RC Unlock(LOCK locktype)
        {
            Debug.Assert(locktype <= LOCK.SHARED);
#if DEBUG
            SysEx.OSTRACE("UNLOCK {0} to {1} was {2}({3})", S.GetHashCode(), locktype, this.Locktype, SharedLockByte);
#endif
            var rc   = RC.OK;
            var type = this.Locktype;
            if (type >= LOCK.EXCLUSIVE)
            {
                lockingStrategy.UnlockFile(this, SHARED_FIRST, SHARED_SIZE);
                if (locktype == LOCK.SHARED && getReadLock() == 0)
                {
                    // This should never happen.  We should always be able to reacquire the read lock
                    rc = winLogError(RC.IOERR_UNLOCK, "winUnlock", Path);
                }
            }
            if (type >= LOCK.RESERVED)
            {
                try { lockingStrategy.UnlockFile(this, RESERVED_BYTE, 1); }
                catch (Exception) { }
            }
            if (locktype == LOCK.NO && type >= LOCK.SHARED)
            {
                unlockReadLock();
            }
            if (type >= LOCK.PENDING)
            {
                try { lockingStrategy.UnlockFile(this, PENDING_BYTE, 1); }
                catch (Exception) { }
            }
            this.Locktype = locktype;
            return(rc);
        }
Exemple #5
0
        public virtual RC CheckReservedLock(ref int pResOut)
        {
            int rc;

            if (Locktype >= LOCK.RESERVED)
            {
                rc = 1;
#if DEBUG
                SysEx.OSTRACE("TEST WR-LOCK {0} {1} (local)", S.Name, rc);
#endif
            }
            else
            {
                try
                {
                    lockingStrategy.LockFile(this, RESERVED_BYTE, 1);
                    lockingStrategy.UnlockFile(this, RESERVED_BYTE, 1);
                    rc = 1;
                }
                catch (IOException) { rc = 0; }
                rc = 1 - rc;
#if DEBUG
                SysEx.OSTRACE("TEST WR-LOCK {0} {1} (remote)", S.GetHashCode(), rc);
#endif
            }
            pResOut = rc;
            return(RC.OK);
        }
Exemple #6
0
        public virtual RC Read(byte[] buffer, int amount, long offset)
        {
            if (buffer == null)
            {
                buffer = new byte[amount];
            }
#if DEBUG
            SysEx.OSTRACE("READ {0} lock={1}", S.GetHashCode(), Locktype);
#endif
            if (!S.CanRead)
            {
                return(RC.IOERR_READ);
            }
            if (seekWinFile(offset) != 0)
            {
                return(RC.FULL);
            }
            int nRead; // Number of bytes actually read from file
            try { nRead = S.Read(buffer, 0, amount); }
            catch (Exception) { LastErrno = (uint)Marshal.GetLastWin32Error(); return(winLogError(RC.IOERR_READ, "winRead", Path)); }
            if (nRead < amount)
            {
                // Unread parts of the buffer must be zero-filled
                Array.Clear(buffer, (int)nRead, (int)(amount - nRead));
                return(RC.IOERR_SHORT_READ);
            }
            return(RC.OK);
        }
        private static PgHdr pcache1Alloc(int nByte)
        {
            PgHdr p = null;

            Debug.Assert(MutexEx.NotHeld(pcache1.grp.mutex));
            StatusEx.sqlite3StatusSet(StatusEx.STATUS.PAGECACHE_SIZE, nByte);
            if (nByte <= pcache1.szSlot)
            {
                MutexEx.Enter(pcache1.mutex);
                p = pcache1.pFree._PgHdr;
                if (p != null)
                {
                    pcache1.pFree = pcache1.pFree.pNext;
                    pcache1.nFreeSlot--;
                    pcache1.bUnderPressure = pcache1.nFreeSlot < pcache1.nReserve;
                    Debug.Assert(pcache1.nFreeSlot >= 0);
                    StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_USED, 1);
                }
                MutexEx.Leave(pcache1.mutex);
            }
            if (p == null)
            {
                // Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get it from sqlite3Malloc instead.
                p = new PgHdr();
                {
                    var sz = nByte;
                    MutexEx.Enter(pcache1.mutex);
                    StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_OVERFLOW, sz);
                    MutexEx.Leave(pcache1.mutex);
                }
                SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.PCACHE);
            }
            return(p);
        }
 private static void pcache1Free(ref PgHdr p)
 {
     if (p == null)
     {
         return;
     }
     if (p.CacheAllocated)
     {
         var pSlot = new PgFreeslot();
         MutexEx.Enter(pcache1.mutex);
         StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_USED, -1);
         pSlot._PgHdr  = p;
         pSlot.pNext   = pcache1.pFree;
         pcache1.pFree = pSlot;
         pcache1.nFreeSlot++;
         pcache1.bUnderPressure = pcache1.nFreeSlot < pcache1.nReserve;
         Debug.Assert(pcache1.nFreeSlot <= pcache1.nSlot);
         MutexEx.Leave(pcache1.mutex);
     }
     else
     {
         Debug.Assert(SysEx.sqlite3MemdebugHasType(p, SysEx.MEMTYPE.PCACHE));
         SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.HEAP);
         var iSize = MallocEx.sqlite3MallocSize(p.Data);
         MutexEx.Enter(pcache1.mutex);
         StatusEx.sqlite3StatusAdd(StatusEx.STATUS.PAGECACHE_OVERFLOW, -iSize);
         MutexEx.Leave(pcache1.mutex);
         MallocEx.sqlite3_free(ref p.Data);
     }
 }
Exemple #9
0
        internal void dropCell(int idx, int sz, ref RC pRC)
        {
            if (pRC != RC.OK)
            {
                return;
            }
            Debug.Assert(idx >= 0 && idx < this.Cells);
#if DEBUG
            Debug.Assert(sz == cellSize(idx));
#endif
            Debug.Assert(Pager.IsPageWriteable(this.DbPage));
            Debug.Assert(MutexEx.Held(this.Shared.Mutex));
            var data = this.Data;
            var ptr  = this.CellOffset + 2 * idx;       // Used to move bytes around within data[]
            var pc   = (uint)ConvertEx.Get2(data, ptr); // Offset to cell content of cell being deleted
            var hdr  = this.HeaderOffset;               // Beginning of the header.  0 most pages.  100 page 1
            if (pc < (uint)ConvertEx.Get2(data, hdr + 5) || pc + sz > this.Shared.UsableSize)
            {
                pRC = SysEx.SQLITE_CORRUPT_BKPT();
                return;
            }
            var rc = freeSpace(pc, sz);
            if (rc != RC.OK)
            {
                pRC = rc;
                return;
            }
            Buffer.BlockCopy(data, ptr + 2, data, ptr, (this.Cells - 1 - idx) * 2);
            this.Cells--;
            data[this.HeaderOffset + 3] = (byte)(this.Cells >> 8);
            data[this.HeaderOffset + 4] = (byte)(this.Cells);
            this.FreeBytes += 2;
        }
        internal static RC autoVacuumCommit(BtShared pBt)
        {
            var rc     = RC.OK;
            var pPager = pBt.Pager;

#if DEBUG
            var nRef = pPager.RefCount;
#else
            var nRef = 0;
#endif
            Debug.Assert(MutexEx.Held(pBt.Mutex));
            Btree.invalidateAllOverflowCache(pBt);
            Debug.Assert(pBt.AutoVacuum);
            if (!pBt.IncrVacuum)
            {
                var nOrig = pBt.btreePagecount(); // Database size before freeing
                if (PTRMAP_ISPAGE(pBt, nOrig) || nOrig == PENDING_BYTE_PAGE(pBt))
                {
                    // It is not possible to create a database for which the final page is either a pointer-map page or the pending-byte page. If one
                    // is encountered, this indicates corruption.
                    return(SysEx.SQLITE_CORRUPT_BKPT());
                }
                var nFree   = (Pgno)ConvertEx.Get4(pBt.Page1.Data, 36);                                    // Number of pages on the freelist initially
                var nEntry  = (int)pBt.UsableSize / 5;                                                     // Number of entries on one ptrmap page
                var nPtrmap = (Pgno)((nFree - nOrig + PTRMAP_PAGENO(pBt, nOrig) + (Pgno)nEntry) / nEntry); // Number of PtrMap pages to be freed
                var nFin    = nOrig - nFree - nPtrmap;                                                     // Number of pages in database after autovacuuming
                if (nOrig > PENDING_BYTE_PAGE(pBt) && nFin < PENDING_BYTE_PAGE(pBt))
                {
                    nFin--;
                }
                while (PTRMAP_ISPAGE(pBt, nFin) || nFin == PENDING_BYTE_PAGE(pBt))
                {
                    nFin--;
                }
                if (nFin > nOrig)
                {
                    return(SysEx.SQLITE_CORRUPT_BKPT());
                }
                for (var iFree = nOrig; iFree > nFin && rc == RC.OK; iFree--)
                {
                    rc = incrVacuumStep(pBt, nFin, iFree);
                }
                if ((rc == RC.DONE || rc == RC.OK) && nFree > 0)
                {
                    rc = Pager.Write(pBt.Page1.DbPage);
                    ConvertEx.Put4(pBt.Page1.Data, 32, 0);
                    ConvertEx.Put4(pBt.Page1.Data, 36, 0);
                    ConvertEx.Put4(pBt.Page1.Data, 28, nFin);
                    pBt.Pager.TruncateImage(nFin);
                    pBt.Pages = nFin;
                }
                if (rc != RC.OK)
                {
                    pPager.Rollback();
                }
            }
            Debug.Assert(nRef == pPager.RefCount);
            return(rc);
        }
        internal RC clearDatabasePage(Pgno pgno, int freePageFlag, ref int pnChange)
        {
            var pPage = new MemPage();

            Debug.Assert(MutexEx.Held(this.Mutex));
            if (pgno > btreePagecount())
            {
                return(SysEx.SQLITE_CORRUPT_BKPT());
            }
            var rc = getAndInitPage(pgno, ref pPage);

            if (rc != RC.OK)
            {
                return(rc);
            }
            for (var i = 0; i < pPage.Cells; i++)
            {
                var iCell = pPage.FindCell(i);
                var pCell = pPage.Data;
                if (pPage.Leaf == 0)
                {
                    rc = clearDatabasePage(ConvertEx.Get4(pCell, iCell), 1, ref pnChange);
                    if (rc != RC.OK)
                    {
                        goto cleardatabasepage_out;
                    }
                }
                rc = pPage.clearCell(iCell);
                if (rc != RC.OK)
                {
                    goto cleardatabasepage_out;
                }
            }
            if (pPage.Leaf == 0)
            {
                rc = clearDatabasePage(ConvertEx.Get4(pPage.Data, 8), 1, ref pnChange);
                if (rc != RC.OK)
                {
                    goto cleardatabasepage_out;
                }
            }
            else
            {
                pnChange += pPage.Cells;
            }
            if (freePageFlag != 0)
            {
                pPage.freePage(ref rc);
            }
            else if ((rc = Pager.Write(pPage.DbPage)) == RC.OK)
            {
                pPage.zeroPage(pPage.Data[0] | Btree.PTF_LEAF);
            }
cleardatabasepage_out:
            pPage.releasePage();
            return(rc);
        }
 internal RC modifyPagePointer(Pgno iFrom, Pgno iTo, PTRMAP eType)
 {
     Debug.Assert(MutexEx.Held(this.Shared.Mutex));
     Debug.Assert(Pager.IsPageWriteable(this.DbPage));
     if (eType == PTRMAP.OVERFLOW2)
     {
         // The pointer is always the first 4 bytes of the page in this case.
         if (ConvertEx.Get4(this.Data) != iFrom)
         {
             return(SysEx.SQLITE_CORRUPT_BKPT());
         }
         ConvertEx.Put4L(this.Data, iTo);
     }
     else
     {
         var isInitOrig = this.HasInit;
         btreeInitPage();
         var nCell = this.Cells;
         int i;
         for (i = 0; i < nCell; i++)
         {
             var pCell = FindCell(i);
             if (eType == PTRMAP.OVERFLOW1)
             {
                 var info = new CellInfo();
                 btreeParseCellPtr(pCell, ref info);
                 if (info.iOverflow != 0)
                 {
                     if (iFrom == ConvertEx.Get4(this.Data, pCell + info.iOverflow))
                     {
                         ConvertEx.Put4(this.Data, pCell + info.iOverflow, (int)iTo);
                         break;
                     }
                 }
             }
             else
             {
                 if (ConvertEx.Get4(this.Data, pCell) == iFrom)
                 {
                     ConvertEx.Put4(this.Data, pCell, (int)iTo);
                     break;
                 }
             }
         }
         if (i == nCell)
         {
             if (eType != PTRMAP.BTREE || ConvertEx.Get4(this.Data, this.HeaderOffset + 8) != iFrom)
             {
                 return(SysEx.SQLITE_CORRUPT_BKPT());
             }
             ConvertEx.Put4L(this.Data, (uint)this.HeaderOffset + 8, iTo);
         }
         this.HasInit = isInitOrig;
     }
     return(RC.OK);
 }
Exemple #13
0
        internal RC defragmentPage()
        {
            Debug.Assert(Pager.IsPageWriteable(this.DbPage));
            Debug.Assert(this.Shared != null);
            Debug.Assert(this.Shared.UsableSize <= Pager.SQLITE_MAX_PAGE_SIZE);
            Debug.Assert(this.NOverflows == 0);
            Debug.Assert(MutexEx.Held(this.Shared.Mutex));
            var temp       = this.Shared.Pager.sqlite3PagerTempSpace(); // Temp area for cell content
            var data       = this.Data;                                 // The page data
            var hdr        = this.HeaderOffset;                         // Offset to the page header
            var cellOffset = this.CellOffset;                           // Offset to the cell pointer array
            var nCell      = this.Cells;                                // Number of cells on the page

            Debug.Assert(nCell == ConvertEx.Get2(data, hdr + 3));
            var usableSize = (int)this.Shared.UsableSize;        // Number of usable bytes on a page
            var cbrk       = (int)ConvertEx.Get2(data, hdr + 5); // Offset to the cell content area

            Buffer.BlockCopy(data, cbrk, temp, cbrk, usableSize - cbrk);
            cbrk = usableSize;
            var iCellFirst = cellOffset + 2 * nCell; // First allowable cell index
            var iCellLast  = usableSize - 4;         // Last possible cell index

            for (var i = 0; i < nCell; i++)
            {
                var pAddr = cellOffset + i * 2;          // The i-th cell pointer
                var pc    = ConvertEx.Get2(data, pAddr); // Address of a i-th cell
#if !SQLITE_ENABLE_OVERSIZE_CELL_CHECK
                // These conditions have already been verified in btreeInitPage() if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
                if (pc < iCellFirst || pc > iCellLast)
                {
                    return(SysEx.SQLITE_CORRUPT_BKPT());
                }
#endif
                Debug.Assert(pc >= iCellFirst && pc <= iCellLast);
                var size = cellSizePtr(temp, pc); // Size of a cell
                cbrk -= size;
                if (cbrk < iCellFirst || pc + size > usableSize)
                {
                    return(SysEx.SQLITE_CORRUPT_BKPT());
                }
                Debug.Assert(cbrk + size <= usableSize && cbrk >= iCellFirst);
                Buffer.BlockCopy(temp, pc, data, cbrk, size);
                ConvertEx.Put2(data, pAddr, cbrk);
            }
            Debug.Assert(cbrk >= iCellFirst);
            ConvertEx.Put2(data, hdr + 5, cbrk);
            data[hdr + 1] = 0;
            data[hdr + 2] = 0;
            data[hdr + 7] = 0;
            var addr = cellOffset + 2 * nCell; // Offset of first byte after cell pointer array
            Array.Clear(data, addr, cbrk - addr);
            Debug.Assert(Pager.IsPageWriteable(this.DbPage));
            return(cbrk - iCellFirst != this.FreeBytes ? SysEx.SQLITE_CORRUPT_BKPT() : RC.OK);
        }
Exemple #14
0
        public virtual RC Sync(SYNC flags)
        {
            // Check that one of SQLITE_SYNC_NORMAL or FULL was passed
            Debug.Assert(((int)flags & 0x0F) == (int)SYNC.NORMAL || ((int)flags & 0x0F) == (int)SYNC.FULL);
            SysEx.OSTRACE("SYNC {0} lock={1}", S.GetHashCode(), Locktype);
#if SQLITE_NO_SYNC
            return(SQLITE.OK);
#else
            S.Flush();
            return(RC.OK);
#endif
        }
Exemple #15
0
        // was:sqlite3PagerDontWrite
        public static void DontWrite(PgHdr pPg)
        {
            var pPager = pPg.Pager;

            if ((pPg.Flags & PgHdr.PGHDR.DIRTY) != 0 && pPager.nSavepoint == 0)
            {
                PAGERTRACE("DONT_WRITE page {0} of {1}", pPg.ID, PAGERID(pPager));
                SysEx.IOTRACE("CLEAN {0:x} {1}", pPager.GetHashCode(), pPg.ID);
                pPg.Flags |= PgHdr.PGHDR.DONT_WRITE;
                pager_set_pagehash(pPg);
            }
        }
Exemple #16
0
        public static void Main(string[] args)
        {
            MutexEx masterMutex;
            RC      rc = SysEx.PreInitialize(out masterMutex);

            if (rc != RC.OK)
            {
                return;
            }
            SysEx.PostInitialize(masterMutex);
            //TestVFS();
            //Console.ReadKey();
        }
 public static RC xInit(object NotUsed)
 {
     SysEx.UNUSED_PARAMETER(NotUsed);
     Debug.Assert(pcache1 == null);
     pcache1 = new PCacheGlobal();
     if (sqlite3GlobalConfig_bCoreMutex)
     {
         pcache1.grp.mutex = MutexEx.sqlite3_mutex_alloc(MutexEx.MUTEX.STATIC_LRU);
         pcache1.mutex     = MutexEx.sqlite3_mutex_alloc(MutexEx.MUTEX.STATIC_PMEM);
     }
     pcache1.grp.mxPinned = 10;
     return(RC.OK);
 }
Exemple #18
0
        private void InputCallback(HMIDIIN hMidiIn, MidiInMessage wMsg,
                                   UIntPtr dwInstance, UIntPtr dwParam1, UIntPtr dwParam2)
        {
            _isInsideInputHandler = true;
            try
            {
                switch (wMsg)
                {
                case MidiInMessage.MIM_DATA:
                {
                    HandleInputMimData(dwParam1, dwParam2);
                    break;
                }

                case MidiInMessage.MIM_LONGDATA:
                {
                    HandleInputMimLongData(dwParam1, dwParam2);
                }
                break;

                case MidiInMessage.MIM_MOREDATA:
                    SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x13 }, 13));
                    break;

                case MidiInMessage.MIM_OPEN:
                    //SysEx(new SysExMessage(this, new byte[] { 0x01 }, 1));
                    break;

                case MidiInMessage.MIM_CLOSE:
                    //SysEx(new SysExMessage(this, new byte[] { 0x02 }, 2));
                    break;

                case MidiInMessage.MIM_ERROR:
                    SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x03 }, 3));
                    break;

                case MidiInMessage.MIM_LONGERROR:
                    SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x04 }, 4));
                    break;

                default:
                    SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x05 }, 5));
                    break;
                }
            }
            finally
            {
                _isInsideInputHandler = false;
            }
        }
Exemple #19
0
 public static RC sqlite3_status(STATUS op, ref int pCurrent, ref int pHighwater, int resetFlag)
 {
     wsdStatInit();
     if (op < 0 || (int)op >= wsdStat.nowValue.Length)
     {
         return(SysEx.SQLITE_MISUSE_BKPT());
     }
     pCurrent   = wsdStat.nowValue[(int)op];
     pHighwater = wsdStat.mxValue[(int)op];
     if (resetFlag != 0)
     {
         wsdStat.mxValue[(int)op] = wsdStat.nowValue[(int)op];
     }
     return(RC.OK);
 }
 private static int pcache1MemSize(object p)
 {
     if (p >= pcache1.pStart && p < pcache1.pEnd)
     {
         return(pcache1.szSlot);
     }
     else
     {
         Debug.Assert(SysEx.sqlite3MemdebugHasType(p, SysEx.MEMTYPE.PCACHE));
         SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.HEAP);
         var iSize = SysEx.sqlite3MallocSize(p);
         SysEx.sqlite3MemdebugSetType(p, SysEx.MEMTYPE.PCACHE);
         return(iSize);
     }
 }
Exemple #21
0
        public virtual RC Close()
        {
            Debug.Assert(Shm == null);
#if DEBUG
            SysEx.OSTRACE("CLOSE {0} ({1})", S.GetHashCode(), S.Name);
#endif
            bool rc;
            int  cnt = 0;
            do
            {
                S.Close();
                rc = true;
            } while (!rc && ++cnt < MX_CLOSE_ATTEMPT);
            return(rc ? RC.OK : winLogError(RC.IOERR_CLOSE, "winClose", Path));
        }
Exemple #22
0
        private RC pagerLockDb(VFSLOCK eLock)
        {
            var rc = RC.OK;

            Debug.Assert(eLock == VFSLOCK.SHARED || eLock == VFSLOCK.RESERVED || eLock == VFSLOCK.EXCLUSIVE);
            if (this.eLock < eLock || this.eLock == VFSLOCK.UNKNOWN)
            {
                rc = this.fd.Lock(eLock);
                if (rc == RC.OK && (this.eLock != VFSLOCK.UNKNOWN || eLock == VFSLOCK.EXCLUSIVE))
                {
                    this.eLock = eLock;
                    SysEx.IOTRACE("LOCK {0:x} {1}", this.GetHashCode(), eLock);
                }
            }
            return(rc);
        }
        internal void ptrmapPut(Pgno key, PTRMAP eType, Pgno parent, ref RC rRC)
        {
            if (rRC != RC.OK)
            {
                return;
            }
            Debug.Assert(MutexEx.Held(this.Mutex));
            // The master-journal page number must never be used as a pointer map page
            Debug.Assert(!MemPage.PTRMAP_ISPAGE(this, MemPage.PENDING_BYTE_PAGE(this)));
            Debug.Assert(this.AutoVacuum);
            if (key == 0)
            {
                rRC = SysEx.SQLITE_CORRUPT_BKPT();
                return;
            }
            var iPtrmap = MemPage.PTRMAP_PAGENO(this, key);
            var pDbPage = new PgHdr();  // The pointer map page
            var rc      = this.Pager.Get(iPtrmap, ref pDbPage);

            if (rc != RC.OK)
            {
                rRC = rc;
                return;
            }
            var offset = (int)MemPage.PTRMAP_PTROFFSET(iPtrmap, key);

            if (offset < 0)
            {
                rRC = SysEx.SQLITE_CORRUPT_BKPT();
                goto ptrmap_exit;
            }
            Debug.Assert(offset <= (int)this.UsableSize - 5);
            var pPtrmap = Pager.sqlite3PagerGetData(pDbPage); // The pointer map data

            if (eType != (PTRMAP)pPtrmap[offset] || ConvertEx.Get4(pPtrmap, offset + 1) != parent)
            {
                Btree.TRACE("PTRMAP_UPDATE: {0}->({1},{2})", key, eType, parent);
                rRC = rc = Pager.Write(pDbPage);
                if (rc == RC.OK)
                {
                    pPtrmap[offset] = (byte)eType;
                    ConvertEx.Put4L(pPtrmap, (uint)offset + 1, parent);
                }
            }
ptrmap_exit:
            Pager.Unref(pDbPage);
        }
Exemple #24
0
        public override RC Truncate(long size)
        {
            SysEx.UNUSED_PARAMETER(size);
            Debug.Assert(size == 0);
            var pChunk = pFirst;

            while (pChunk != null)
            {
                var pTmp = pChunk;
                pChunk = pChunk.pNext;
            }
            // clear
            pFirst    = null;
            endpoint  = new FilePoint();
            readpoint = new FilePoint();
            return(RC.OK);
        }
Exemple #25
0
        public virtual RC Truncate(long size)
        {
            var rc = RC.OK;

#if DEBUG
            SysEx.OSTRACE("TRUNCATE {0} {1,11}", S.Name, size);
#endif
            // If the user has configured a chunk-size for this file, truncate the file so that it consists of an integer number of chunks (i.e. the
            // actual file size after the operation may be larger than the requested size).
            if (Chunk != 0)
            {
                size = ((size + Chunk - 1) / Chunk) * Chunk;
            }
            try { S.SetLength(size); rc = RC.OK; }
            catch (IOException e) { LastErrno = (uint)Marshal.GetLastWin32Error(); rc = winLogError(RC.IOERR_TRUNCATE, "winTruncate2", Path); }
            SysEx.OSTRACE("TRUNCATE {0} {1,%11} {2}", S.GetHashCode(), size, rc == RC.OK ? "ok" : "failed");
            return(rc);
        }
Exemple #26
0
        private RC pagerUnlockDb(VFSLOCK eLock)
        {
            var rc = RC.OK;

            Debug.Assert(!this.exclusiveMode || this.eLock == eLock);
            Debug.Assert(eLock == VFSLOCK.NO || eLock == VFSLOCK.SHARED);
            Debug.Assert(eLock != VFSLOCK.NO || !this.pagerUseWal());
            if (this.fd.IsOpen)
            {
                Debug.Assert(this.eLock >= eLock);
                rc = this.fd.Unlock(eLock);
                if (this.eLock != VFSLOCK.UNKNOWN)
                {
                    this.eLock = eLock;
                }
                SysEx.IOTRACE("UNLOCK {0:x} {1}", this.GetHashCode(), eLock);
            }
            return(rc);
        }
Exemple #27
0
        static void Stat3Init_(FuncContext fctx, int argc, Mem[][] argv)
        {
            tRowcnt    rows       = (tRowcnt)Vdbe.Value_Int64(argv[0]);
            int        maxSamples = Vdbe.Value_Int(argv[1]);
            int        n          = maxSamples;
            Stat3Accum p          = new Stat3Accum
            {
                a          = new array_t <Stat3Accum.Stat3Sample>(new Stat3Accum.Stat3Sample[n]),
                Rows       = rows,
                MaxSamples = maxSamples,
                PSamples   = (uint)(rows / (maxSamples / 3 + 1) + 1),
            };

            if (p == null)
            {
                Vdbe.Result_ErrorNoMem(fctx);
                return;
            }
            SysEx.Randomness(-1, p.Prn);
            Vdbe.Result_Blob(fctx, p, -1, C._free);
        }
        internal bool removeFromSharingList()
        {
#if !SQLITE_OMIT_SHARED_CACHE
            MutexEx  pMaster;
            BtShared list;
            bool     removed = false;
            Debug.Assert(MutexEx.NotHeld(Mutex));
            pMaster = MutexEx.Alloc(MUTEX.STATIC_MASTER);
            MutexEx.Enter(pMaster);
            nRef--;
            if (nRef <= 0)
            {
                if (SysEx.getGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList) == this)
                {
                    SysEx.setGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList, Next);
                }
                else
                {
                    list = SysEx.getGLOBAL <BtShared>(Btree.s_sqlite3SharedCacheList);
                    while (Check.ALWAYS(list) != null && list.Next != this)
                    {
                        list = list.Next;
                    }
                    if (Check.ALWAYS(list) != null)
                    {
                        list.Next = Next;
                    }
                }
                if (MutexEx.SQLITE_THREADSAFE)
                {
                    MutexEx.Free(Mutex);
                }
                removed = true;
            }
            MutexEx.Leave(pMaster);
            return(removed);
#else
            return(true);
#endif
        }
Exemple #29
0
        public override RC Write(byte[] zBuf, int iAmt, long iOfst)
        {
            SysEx.UNUSED_PARAMETER(iOfst);
            // An in-memory journal file should only ever be appended to. Random access writes are not required by sqlite.
            Debug.Assert(iOfst == endpoint.iOffset);
            var izWrite = 0;

            while (iAmt > 0)
            {
                var pChunk       = endpoint.pChunk;
                var iChunkOffset = (int)(endpoint.iOffset % JOURNAL_CHUNKSIZE);
                var iSpace       = Math.Min(iAmt, JOURNAL_CHUNKSIZE - iChunkOffset);
                if (iChunkOffset == 0)
                {
                    // New chunk is required to extend the file.
                    var pNew = new FileChunk();
                    if (pNew == null)
                    {
                        return(RC.IOERR_NOMEM);
                    }
                    pNew.pNext = null;
                    if (pChunk != null)
                    {
                        Debug.Assert(pFirst != null); pChunk.pNext = pNew;
                    }
                    else
                    {
                        Debug.Assert(pFirst == null); pFirst = pNew;
                    }
                    endpoint.pChunk = pNew;
                }
                Buffer.BlockCopy(zBuf, izWrite, endpoint.pChunk.zChunk, iChunkOffset, iSpace);
                izWrite          += iSpace;
                iAmt             -= iSpace;
                endpoint.iOffset += iSpace;
            }
            return(RC.OK);
        }
 private static void sqlite3PCacheBufferSetup(object pBuf, int sz, int n)
 {
     if (pcache1 != null)
     {
         sz                     = SysEx.ROUNDDOWN8(sz);
         pcache1.szSlot         = sz;
         pcache1.nSlot          = pcache1.nFreeSlot = n;
         pcache1.nReserve       = n > 90 ? 10 : (n / 10 + 1);
         pcache1.pStart         = null;
         pcache1.pEnd           = null;
         pcache1.pFree          = null;
         pcache1.bUnderPressure = false;
         PgFreeslot p;
         while (n-- > 0)
         {
             p             = new PgFreeslot();
             p._PgHdr      = new PgHdr();
             p.pNext       = pcache1.pFree;
             pcache1.pFree = p;
         }
         pcache1.pEnd = pBuf;
     }
 }