예제 #1
0
 // was:sqlite3PcacheClose
 internal void Close()
 {
     if (pCache != null)
     {
         IPCache.xDestroy(ref pCache);
     }
 }
예제 #2
0
 // was:sqlite3PcacheSetPageSize
 internal void SetPageSize(int szPage)
 {
     Debug.Assert(nRef == 0 && pDirty == null);
     if (pCache != null)
     {
         IPCache.xDestroy(ref pCache);
         pCache = null;
     }
     this.szPage = szPage;
 }
예제 #3
0
 public static void xDestroy(ref IPCache pCache)
 {
     PGroup pGroup = pCache.pGroup;
     Debug.Assert(pCache.bPurgeable || (pCache.nMax == 0 && pCache.nMin == 0));
     pcache1EnterMutex(pGroup);
     pCache.pcache1TruncateUnsafe(0);
     pGroup.nMaxPage -= pCache.nMax;
     pGroup.nMinPage -= pCache.nMin;
     pGroup.mxPinned = pGroup.nMaxPage + 10 - pGroup.nMinPage;
     pcache1EnforceMaxPage(pGroup);
     pcache1LeaveMutex(pGroup);
     pCache = null;
 }
예제 #4
0
        public static void xDestroy(ref IPCache pCache)
        {
            PGroup pGroup = pCache.pGroup;

            Debug.Assert(pCache.bPurgeable || (pCache.nMax == 0 && pCache.nMin == 0));
            pcache1EnterMutex(pGroup);
            pCache.pcache1TruncateUnsafe(0);
            pGroup.nMaxPage -= pCache.nMax;
            pGroup.nMinPage -= pCache.nMin;
            pGroup.mxPinned  = pGroup.nMaxPage + 10 - pGroup.nMinPage;
            pcache1EnforceMaxPage(pGroup);
            pcache1LeaveMutex(pGroup);
            pCache = null;
        }
예제 #5
0
        // was:sqlite3PagerSetPagesize
        public RC SetPageSize(ref uint pPageSize, int nReserve)
        {
            // It is not possible to do a full assert_pager_state() here, as this function may be called from within PagerOpen(), before the state
            // of the Pager object is internally consistent.
            // At one point this function returned an error if the pager was in PAGER_ERROR state. But since PAGER_ERROR state guarantees that
            // there is at least one outstanding page reference, this function is a no-op for that case anyhow.
            var rc       = RC.OK;
            var pageSize = pPageSize;

            Debug.Assert(pageSize == 0 || (pageSize >= 512 && pageSize <= SQLITE_MAX_PAGE_SIZE));
            if ((this.memDb == 0 || this.dbSize == 0) && this.pPCache.sqlite3PcacheRefCount() == 0 && pageSize != 0 && pageSize != (uint)this.pageSize)
            {
                long nByte = 0;
                if (this.eState > PAGER.OPEN && this.fd.IsOpen)
                {
                    rc = this.fd.FileSize(ref nByte);
                }
                if (rc == RC.OK)
                {
                    pager_reset();
                    this.dbSize   = (Pgno)(nByte / pageSize);
                    this.pageSize = (int)pageSize;
                    IPCache.sqlite3PageFree(ref this.pTmpSpace);
                    this.pTmpSpace = MallocEx.sqlite3Malloc((int)pageSize);
                    this.pPCache.SetPageSize((int)pageSize);
                }
            }
            pPageSize = (uint)this.pageSize;
            if (rc == RC.OK)
            {
                if (nReserve < 0)
                {
                    nReserve = this.nReserve;
                }
                Debug.Assert(nReserve >= 0 && nReserve < 1000);
                this.nReserve = (short)nReserve;
                pagerReportSize();
            }
            return(rc);
        }
예제 #6
0
        // was:sqlite3PcacheFetch
        internal RC FetchPage(Pgno pgno, int createFlag, ref PgHdr ppPage)
        {
            Debug.Assert(createFlag == 1 || createFlag == 0);
            Debug.Assert(pgno > 0);
            // If the pluggable cache (sqlite3_pcache*) has not been allocated, allocate it now.
            if (pCache == null && createFlag != 0)
            {
                var nByte = szPage + szExtra + 0;
                var p     = IPCache.xCreate(nByte, bPurgeable);
                p.xCachesize(nMax);
                pCache = p;
            }
            var   eCreate = createFlag * (1 + ((!bPurgeable || null == pDirty) ? 1 : 0));
            PgHdr pPage   = null;

            if (pCache != null)
            {
                pPage = pCache.xFetch(pgno, eCreate);
            }
            if (pPage == null && eCreate == 1)
            {
                PgHdr pPg;
                // Find a dirty page to write-out and recycle. First try to find a page that does not require a journal-sync (one with PGHDR_NEED_SYNC
                // cleared), but if that is not possible settle for any other unreferenced dirty page.
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
                expensive_assert(pcacheCheckSynced(pCache));
#endif
                for (pPg = pSynced; pPg != null && (pPg.Refs != 0 || (pPg.Flags & PgHdr.PGHDR.NEED_SYNC) != 0); pPg = pPg.DirtyPrev)
                {
                    ;
                }
                pSynced = pPg;
                if (pPg == null)
                {
                    for (pPg = pDirtyTail; pPg != null && pPg.Refs != 0; pPg = pPg.DirtyPrev)
                    {
                        ;
                    }
                }
                if (pPg != null)
                {
#if SQLITE_LOG_CACHE_SPILL
                    sqlite3_log(SQLITE_FULL, "spill page %d making room for %d - cache used: %d/%d", pPg.pgno, pgno, sqlite3GlobalConfig.pcache.xPagecount(pCache.pCache), pCache.nMax);
#endif
                    var rc = xStress(pStress, pPg);
                    if (rc != RC.OK && rc != RC.BUSY)
                    {
                        return(rc);
                    }
                }
                pPage = pCache.xFetch(pgno, 2);
            }
            if (pPage != null)
            {
                if (pPage.Data == null)
                {
                    pPage.Data  = MallocEx.sqlite3Malloc(pCache.szPage);
                    pPage.Cache = this;
                    pPage.ID    = pgno;
                }
                Debug.Assert(pPage.Cache == this);
                Debug.Assert(pPage.ID == pgno);
                if (pPage.Refs == 0)
                {
                    nRef++;
                }
                pPage.Refs++;
                if (pgno == 1)
                {
                    pPage1 = pPage;
                }
            }
            ppPage = pPage;
            return(pPage == null && eCreate != 0 ? RC.NOMEM : RC.OK);
        }
예제 #7
0
 private static void sqlite3PcacheShutdown()
 {
     IPCache.xShutdown(IPCache.pArg);
 }
예제 #8
0
 private static RC sqlite3PcacheInitialize()
 {
     return(IPCache.xInit(IPCache.pArg));
 }