public static void AddToDirtyList(PgHdr page) { var p = page.Cache; page.DirtyNext = p.Dirty; if (page.DirtyNext != null) { page.DirtyNext.DirtyPrev = page; } p.Dirty = page; if (p.DirtyTail == null) { p.DirtyTail = page; } if ((p.Synced == null) && (0 == (page.Flags & PGHDR.NEED_SYNC))) { p.Synced = page; } }
//private int Fetch(uint pgno, bool createFlag, ref PgHdr ppPage) //{ // PgHdr page = null; // int eCreate; // // If the pluggable cache (sqlite3_pcache*) has not been allocated, allocate it now. // if ((Cache == null) && createFlag) // { // int bytes = PageSize + ExtraSize + sizeof(PgHdr); // var p = sqlite3GlobalConfig_pcache.Create(bytes, Purgeable); // if (p == null) // rc = SQLITE_NOMEM; // sqlite3GlobalConfig_pcache.Cachesize(p, Max); // Cache = p; // } // eCreate = createFlag * (1 + (!Purgeable || (Dirty == null))); // if (Cache != null) // page = sqlite3GlobalConfig_pcache.Fetch(Cache, pgno, eCreate); // if (!page && 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. // for (pPg = Synced; (pPg != null) && ((pPg.Ref != 0) || ((pPg.Flags & PGHDR.NEED_SYNC) != 0)); pPg = pPg.DirtyPrev) { } // Synced = pPg; // if (pPg == null) // for (pPg = DirtyTail; (pPg != null) && (pPg.Ref != 0); pPg = pPg.DirtyPrev) { } // if (pPg != null) // { // int rc; // rc = Stress(StressArg, pPg); // if (rc != SQLITE_OK && rc != SQLITE_BUSY) // return rc; // } // page = sqlite3GlobalConfig_pcache.xFetch(pCache->pCache, pgno, 2); // } // if (page) // { // if (!page->pData) // { // memset(page, 0, sizeof(PgHdr)); // page->pData = (void*)&page[1]; // page->pExtra = (void*)&((char*)page->pData)[pCache->szPage]; // memset(page->pExtra, 0, pCache->szExtra); // page->pCache = pCache; // page->pgno = pgno; // } // if (0 == page->nRef) // pCache->nRef++; // page->nRef++; // if (pgno == 1) // pCache->pPage1 = page; // } // ppPage = page; // return ((page == 0) && eCreate ? SQLITE_NOMEM : SQLITE_OK); //} private static void Release(PgHdr p) { Contract.Assert(p.Ref > 0); p.Ref--; if (p.Ref == 0) { var cache = p.Cache; cache.Ref--; if ((p.Flags & PGHDR.DIRTY) == 0) { Unpin(p); } else { // Move the page to the head of the dirty list. RemoveFromDirtyList(p); AddToDirtyList(p); } } }
private static PgHdr SortDirtyList(PgHdr pIn) { var a = new PgHdr[N_SORT_BUCKET]; PgHdr p; //memset(a, 0, sizeof(a)); while (pIn != null) { p = pIn; pIn = p.Dirty; p.Dirty = null; int i; for (i = 0; i < N_SORT_BUCKET - 1; i++) { if (a[i] == null) { a[i] = p; break; } else { p = MergeDirtyList(a[i], p); a[i] = null; } } if (i == N_SORT_BUCKET - 1) { // To get here, there need to be 2^(N_SORT_BUCKET) elements in the input list. But that is impossible. a[i] = MergeDirtyList(a[i], p); } } p = a[0]; for (int i = 1; i < N_SORT_BUCKET; i++) { p = MergeDirtyList(p, a[i]); } return(p); }
private static int PageRefcount(PgHdr p) { return(p.Ref); }
private static void Ref2(PgHdr p) { p.Ref++; }