/* ** Close a cache. */ static void sqlite3PcacheClose(PCache pCache) { if (pCache.pCache != null) { sqlite3GlobalConfig.pcache.xDestroy(ref pCache.pCache); } }
/* ** Drop every cache entry whose page number is greater than "pgno". The ** caller must ensure that there are no outstanding references to any pages ** other than page 1 with a page number greater than pgno. ** ** If there is a reference to page 1 and the pgno parameter passed to this ** function is 0, then the data area associated with page 1 is zeroed, but ** the page object is not dropped. */ private static void sqlite3PcacheTruncate(PCache pCache, uint pgno) { if (pCache.pCache != null) { PgHdr p; PgHdr pNext; for (p = pCache.pDirty; p != null; p = pNext) { pNext = p.pDirtyNext; if (p.pgno > pgno) { Debug.Assert((p.flags & PGHDR_DIRTY) != 0); sqlite3PcacheMakeClean(p); } } if (pgno == 0 && pCache.pPage1 != null) { // memset( pCache.pPage1.pData, 0, pCache.szPage ); pCache.pPage1.pData = sqlite3Malloc(pCache.szPage); pgno = 1; } sqlite3GlobalConfig.pcache.xTruncate(pCache.pCache, pgno + 1); } }
//# define expensive_assert(X) #endif /********************************** Linked List Management ********************/ #if !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT /* ** Check that the pCache.pSynced variable is set correctly. If it ** is not, either fail an Debug.Assert or return zero. Otherwise, return ** non-zero. This is only used in debugging builds, as follows: ** ** expensive_assert( pcacheCheckSynced(pCache) ); */ static int pcacheCheckSynced(PCache pCache){ PgHdr p ; for(p=pCache.pDirtyTail; p!=pCache.pSynced; p=p.pDirtyPrev){ Debug.Assert( p.nRef !=0|| (p.flags&PGHDR_NEED_SYNC) !=0); } return (p==null || p.nRef!=0 || (p.flags&PGHDR_NEED_SYNC)==0)?1:0; }
/* ** Add page pPage to the head of the dirty list (PCache1.pDirty is set to ** pPage). */ static void pcacheAddToDirtyList(PgHdr pPage) { PCache p = pPage.pCache; Debug.Assert(pPage.pDirtyNext == null && pPage.pDirtyPrev == null && p.pDirty != pPage); pPage.pDirtyNext = p.pDirty; if (pPage.pDirtyNext != null) { Debug.Assert(pPage.pDirtyNext.pDirtyPrev == null); pPage.pDirtyNext.pDirtyPrev = pPage; } p.pDirty = pPage; if (null == p.pDirtyTail) { p.pDirtyTail = pPage; } if (null == p.pSynced && 0 == (pPage.flags & PGHDR_NEED_SYNC)) { p.pSynced = pPage; } #if SQLITE_ENABLE_EXPENSIVE_ASSERT expensive_assert(pcacheCheckSynced(p)); #endif }
/* ** Drop every cache entry whose page number is greater than "pgno". The ** caller must ensure that there are no outstanding references to any pages ** other than page 1 with a page number greater than pgno. ** ** If there is a reference to page 1 and the pgno parameter passed to this ** function is 0, then the data area associated with page 1 is zeroed, but ** the page object is not dropped. */ static void sqlite3PcacheTruncate(PCache pCache, u32 pgno) { if (pCache.pCache != null) { PgHdr p; PgHdr pNext; for (p = pCache.pDirty; p != null; p = pNext) { pNext = p.pDirtyNext; /* This routine never gets call with a positive pgno except right ** after sqlite3PcacheCleanAll(). So if there are dirty pages, ** it must be that pgno==0. */ Debug.Assert(p.pgno > 0); if (ALWAYS(p.pgno > pgno)) { Debug.Assert((p.flags & PGHDR_DIRTY) != 0); sqlite3PcacheMakeClean(p); } } if (pgno == 0 && pCache.pPage1 != null) { // memset( pCache.pPage1.pData, 0, pCache.szPage ); pCache.pPage1.pData = sqlite3Malloc(pCache.szPage); pgno = 1; } sqlite3GlobalConfig.pcache.xTruncate(pCache.pCache, pgno + 1); } }
/* ** For all dirty pages currently in the cache, invoke the specified ** callback. This is only used if the SQLITE_CHECK_PAGES macro is ** defined. */ static void sqlite3PcacheIterateDirty( PCache pCache, dxIter xIter ) { PgHdr pDirty; for ( pDirty = pCache.pDirty; pDirty != null; pDirty = pDirty.pDirtyNext ) { xIter( pDirty ); } }
/* ** Make every page in the cache clean. */ static void sqlite3PcacheCleanAll( PCache pCache ) { PgHdr p; while ( ( p = pCache.pDirty ) != null ) { sqlite3PcacheMakeClean( p ); } }
/* ** Set the suggested cache-size value. */ static void sqlite3PcacheSetCachesize(PCache pCache, int mxPage) { pCache.nMax = mxPage; if (pCache.pCache != null) { sqlite3GlobalConfig.pcache.xCachesize(pCache.pCache, mxPage); } }
/* ** Return the total number of pages in the cache. */ static int sqlite3PcachePagecount( PCache pCache ) { int nPage = 0; if ( pCache.pCache != null ) { nPage = sqlite3GlobalConfig.pcache.xPagecount( pCache.pCache ); } return nPage; }
/* ** Return a list of all dirty pages in the cache, sorted by page number. */ static PgHdr sqlite3PcacheDirtyList( PCache pCache ) { PgHdr p; for ( p = pCache.pDirty; p != null; p = p.pDirtyNext ) { p.pDirty = p.pDirtyNext; } return pcacheSortDirtyList( pCache.pDirty ); }
/* ** Clear the PGHDR_NEED_SYNC flag from all dirty pages. */ static void sqlite3PcacheClearSyncFlags( PCache pCache ) { PgHdr p; for ( p = pCache.pDirty; p != null; p = p.pDirtyNext ) { p.flags &= ~PGHDR_NEED_SYNC; } pCache.pSynced = pCache.pDirtyTail; }
/* ** Return the total number of pages in the cache. */ private static int sqlite3PcachePagecount(PCache pCache) { var nPage = 0; if (pCache.pCache != null) { nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache.pCache); } return(nPage); }
/* ** Change the page size for PCache object. The caller must ensure that there ** are no outstanding page references when this function is called. */ static void sqlite3PcacheSetPageSize(PCache pCache, int szPage) { Debug.Assert(pCache.nRef == 0 && pCache.pDirty == null); if (pCache.pCache != null) { sqlite3GlobalConfig.pcache.xDestroy(ref pCache.pCache); pCache.pCache = null; } pCache.szPage = szPage; }
/* ** Wrapper around the pluggable caches xUnpin method. If the cache is ** being used for an in-memory database, this function is a no-op. */ static void pcacheUnpin( PgHdr p ) { PCache pCache = p.pCache; if ( pCache.bPurgeable ) { if ( p.pgno == 1 ) { pCache.pPage1 = null; } sqlite3GlobalConfig.pcache.xUnpin( pCache.pCache, p, false ); } }
/* ** Change the page number of page p to newPgno. */ static void sqlite3PcacheMove( PgHdr p, Pgno newPgno ) { PCache pCache = p.pCache; Debug.Assert( p.nRef > 0 ); Debug.Assert( newPgno > 0 ); sqlite3GlobalConfig.pcache.xRekey( pCache.pCache, p, p.pgno, newPgno ); p.pgno = newPgno; if ( ( p.flags & PGHDR_DIRTY ) != 0 && ( p.flags & PGHDR_NEED_SYNC ) != 0 ) { pcacheRemoveFromDirtyList( p ); pcacheAddToDirtyList( p ); } }
public void Clear() { this.pData = null; this.pExtra = null; this.pDirty = null; this.pgno = 0; this.pPager = null; #if SQLITE_CHECK_PAGES this.pageHash = 0; #endif this.flags = 0; this.nRef = 0; this.pCache = null; this.pDirtyNext = null; this.pDirtyPrev = null; this.pPgHdr1 = null; }
}// sizeof( PCache ); } /* ** Create a new PCache object. Storage space to hold the object ** has already been allocated and is passed in as the p pointer. ** The caller discovers how much space needs to be allocated by ** calling sqlite3PcacheSize(). */ static void sqlite3PcacheOpen( int szPage, /* Size of every page */ int szExtra, /* Extra space associated with each page */ bool bPurgeable, /* True if pages are on backing store */ dxStress xStress, //int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ object pStress, /* Argument to xStress */ PCache p /* Preallocated space for the PCache */ ) { p.Clear();//memset(p, 0, sizeof(PCache)); p.szPage = szPage; p.szExtra = szExtra; p.bPurgeable = bPurgeable; p.xStress = xStress; p.pStress = pStress; p.nMax = 100; }
public void Clear() { sqlite3_free(ref pData); pData = null; pExtra = null; pDirty = null; pgno = 0; pPager = null; #if SQLITE_CHECK_PAGES this.pageHash = 0; #endif flags = 0; nRef = 0; pCache = null; pDirtyNext = null; pDirtyPrev = null; pPgHdr1 = null; }
public void Clear() { sqlite3_free(ref this.pData); this.pData = null; this.pExtra = null; this.pDirty = null; this.pgno = 0; this.pPager = null; #if SQLITE_CHECK_PAGES this.pageHash=0; #endif this.flags = 0; this.nRef = 0; this.CacheAllocated = false; this.pCache = null; this.pDirtyNext = null; this.pDirtyPrev = null; this.pPgHdr1 = null; }
/* ** Remove page pPage from the list of dirty pages. */ static void pcacheRemoveFromDirtyList(PgHdr pPage) { PCache p = pPage.pCache; Debug.Assert(pPage.pDirtyNext != null || pPage == p.pDirtyTail); Debug.Assert(pPage.pDirtyPrev != null || pPage == p.pDirty); /* Update the PCache1.pSynced variable if necessary. */ if (p.pSynced == pPage) { PgHdr pSynced = pPage.pDirtyPrev; while (pSynced != null && (pSynced.flags & PGHDR_NEED_SYNC) != 0) { pSynced = pSynced.pDirtyPrev; } p.pSynced = pSynced; } if (pPage.pDirtyNext != null) { pPage.pDirtyNext.pDirtyPrev = pPage.pDirtyPrev; } else { Debug.Assert(pPage == p.pDirtyTail); p.pDirtyTail = pPage.pDirtyPrev; } if (pPage.pDirtyPrev != null) { pPage.pDirtyPrev.pDirtyNext = pPage.pDirtyNext; } else { Debug.Assert(pPage == p.pDirty); p.pDirty = pPage.pDirtyNext; } pPage.pDirtyNext = null; pPage.pDirtyPrev = null; #if SQLITE_ENABLE_EXPENSIVE_ASSERT expensive_assert(pcacheCheckSynced(p)); #endif }
public void Clear() { sqlite3_free(ref this.pData); this.pData = null; this.pExtra = null; this.pDirty = null; this.pgno = 0; this.pPager = null; #if SQLITE_CHECK_PAGES this.pageHash = 0; #endif this.flags = 0; this.nRef = 0; this.CacheAllocated = false; this.pCache = null; this.pDirtyNext = null; this.pDirtyPrev = null; this.pPgHdr1 = null; }
/* ** Decrement the reference count on a page. If the page is clean and the ** reference count drops to 0, then it is made elible for recycling. */ static void sqlite3PcacheRelease(PgHdr p) { Debug.Assert(p.nRef > 0); p.nRef--; if (p.nRef == 0) { PCache pCache = p.pCache; pCache.nRef--; if ((p.flags & PGHDR_DIRTY) == 0) { pcacheUnpin(p); } else { /* Move the page to the head of the dirty list. */ pcacheRemoveFromDirtyList(p); pcacheAddToDirtyList(p); } } }
//RESTORE public Form1() { cacheFile = Application.StartupPath + "\\MyObj.bin"; InitializeComponent(); _cache = new PCache(); if (File.Exists(cacheFile)) { FileStream fs = new FileStream(cacheFile, FileMode.Open, FileAccess.Read, FileShare.None); byte[] array = new byte[fs.Length]; fs.Read(array, 0, (Int32)fs.Length); fs.Close(); //below simple method converts saved byte data into cache object if(array.Length>0) _cache.RestoreCache(array, true); } CleanView(true); }
//RESTORE public Form1() { cacheFile = Application.StartupPath + "\\MyObj.bin"; InitializeComponent(); _cache = new PCache(); if (File.Exists(cacheFile)) { FileStream fs = new FileStream(cacheFile, FileMode.Open, FileAccess.Read, FileShare.None); byte[] array = new byte[fs.Length]; fs.Read(array, 0, (Int32)fs.Length); fs.Close(); //below simple method converts saved byte data into cache object if (array.Length > 0) { _cache.RestoreCache(array, true); } } CleanView(true); }
/* ** Close a cache. */ static void sqlite3PcacheClose( PCache pCache ) { if ( pCache.pCache != null ) { sqlite3GlobalConfig.pcache.xDestroy( ref pCache.pCache ); } }
/* ** Discard the contents of the cache. */ static void sqlite3PcacheClear( PCache pCache ) { sqlite3PcacheTruncate( pCache, 0 ); }
/* ** Drop every cache entry whose page number is greater than "pgno". The ** caller must ensure that there are no outstanding references to any pages ** other than page 1 with a page number greater than pgno. ** ** If there is a reference to page 1 and the pgno parameter passed to this ** function is 0, then the data area associated with page 1 is zeroed, but ** the page object is not dropped. */ static void sqlite3PcacheTruncate( PCache pCache, u32 pgno ) { if ( pCache.pCache != null ) { PgHdr p; PgHdr pNext; for ( p = pCache.pDirty; p != null; p = pNext ) { pNext = p.pDirtyNext; /* This routine never gets call with a positive pgno except right ** after sqlite3PcacheCleanAll(). So if there are dirty pages, ** it must be that pgno==0. */ Debug.Assert( p.pgno > 0 ); if ( ALWAYS( p.pgno > pgno ) ) { Debug.Assert( ( p.flags & PGHDR_DIRTY ) != 0 ); sqlite3PcacheMakeClean( p ); } } if ( pgno == 0 && pCache.pPage1 != null ) { // memset( pCache.pPage1.pData, 0, pCache.szPage ); pCache.pPage1.pData = sqlite3Malloc( pCache.szPage ); pgno = 1; } sqlite3GlobalConfig.pcache.xTruncate( pCache.pCache, pgno + 1 ); } }
/* ** Get the suggested cache-size value. */ static int sqlite3PcacheGetCachesize(PCache pCache) { return(pCache.nMax); }
}// sizeof( PCache ); } /* ** Create a new PCache object. Storage space to hold the object ** has already been allocated and is passed in as the p pointer. ** The caller discovers how much space needs to be allocated by ** calling sqlite3PcacheSize(). */ static void sqlite3PcacheOpen( int szPage, /* Size of every page */ int szExtra, /* Extra space associated with each page */ bool bPurgeable, /* True if pages are on backing store */ dxStress xStress,//int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ object pStress, /* Argument to xStress */ PCache p /* Preallocated space for the PCache */ ) { p.Clear();//memset(p, 0, sizeof(PCache)); p.szPage = szPage; p.szExtra = szExtra; p.bPurgeable = bPurgeable; p.xStress = xStress; p.pStress = pStress; p.nMax = 100; }
public void Clear() { this.pData = null; this.pExtra = null; this.pDirty = null; this.pgno = 0; this.pPager = null; #if SQLITE_CHECK_PAGES this.pageHash=0; #endif this.flags = 0; this.nRef = 0; this.pCache = null; this.pDirtyNext = null; this.pDirtyPrev = null; this.pPgHdr1 = null; }
public static PCache ComputePCacheFromMesh(Mesh mesh, int mapSize = 512, int pointCount = 4096, int seed = 0, Distribution distribution = Distribution.RandomUniformArea, MeshBakeMode meshBakeMode = MeshBakeMode.Triangle) { if (mapSize % 8 != 0) { Debug.LogError("Position map dimensions should be a multiple of 8."); return(null); } if (computeShader == null) { computeShader = computeShader = Resources.Load <ComputeShader>("Shaders/ComputeMeshToMap"); } PCache pCache = new PCache(); // From PointCacheBakeTool MeshData meshCache = ComputeDataCache(mesh); Picker picker = null; if (distribution == Distribution.Sequential) { if (meshBakeMode == MeshBakeMode.Vertex) { picker = new SequentialPickerVertex(meshCache); } else if (meshBakeMode == MeshBakeMode.Triangle) { picker = new SequentialPickerTriangle(meshCache); } } else if (distribution == Distribution.Random) { if (meshBakeMode == MeshBakeMode.Vertex) { picker = new RandomPickerVertex(meshCache, seed); } else if (meshBakeMode == MeshBakeMode.Triangle) { picker = new RandomPickerTriangle(meshCache, seed); } } else if (distribution == Distribution.RandomUniformArea) { picker = new RandomPickerUniformArea(meshCache, seed); } if (picker == null) { throw new InvalidOperationException("Unable to find picker"); } pCache.mesh = mesh; pCache.mapSize = mapSize; pCache.positions = new List <Vector3>(); pCache.normals = new List <Vector3>(); for (int i = 0; i < pointCount; ++i) { var vertex = picker.GetNext(); pCache.positions.Add(vertex.position); pCache.normals.Add(vertex.normal); } // From SMRVFX pCache.positionMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat); pCache.positionMap.enableRandomWrite = true; pCache.positionMap.Create(); pCache.normalMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat); pCache.normalMap.enableRandomWrite = true; pCache.normalMap.Create(); // Transfer data var vcount = pCache.positions.Count; var vcount_x3 = vcount * 3; pCache.positionBuffer = new ComputeBuffer(vcount_x3, sizeof(float)); pCache.normalBuffer = new ComputeBuffer(vcount_x3, sizeof(float)); computeShader.SetInt("VertexCount", vcount); pCache.positionBuffer.SetData(pCache.positions); pCache.normalBuffer.SetData(pCache.normals); computeShader.SetBuffer(0, "PositionBuffer", pCache.positionBuffer); computeShader.SetBuffer(0, "NormalBuffer", pCache.normalBuffer); computeShader.SetTexture(0, "PositionMap", pCache.positionMap); computeShader.SetTexture(0, "NormalMap", pCache.normalMap); computeShader.Dispatch(0, pCache.mapSize / 8, pCache.mapSize / 8, 1); return(pCache); }
/* ** Try to obtain a page from the cache. */ static int sqlite3PcacheFetch( PCache pCache, /* Obtain the page from this cache */ u32 pgno, /* Page number to obtain */ int createFlag, /* If true, create page if it does not exist already */ ref PgHdr ppPage /* Write the page here */ ) { PgHdr pPage = null; int eCreate; Debug.Assert(pCache != null); Debug.Assert(createFlag == 1 || createFlag == 0); Debug.Assert(pgno > 0); /* If the pluggable cache (sqlite3_pcache*) has not been allocated, ** allocate it now. */ if (null == pCache.pCache && createFlag != 0) { sqlite3_pcache p; int nByte; nByte = pCache.szPage + pCache.szExtra + 0;// sizeof( PgHdr ); p = sqlite3GlobalConfig.pcache.xCreate(nByte, pCache.bPurgeable); if (null == p) { return(SQLITE_NOMEM); } sqlite3GlobalConfig.pcache.xCachesize(p, pCache.nMax); pCache.pCache = p; } eCreate = createFlag * (1 + ((!pCache.bPurgeable || null == pCache.pDirty) ? 1 : 0)); if (pCache.pCache != null) { pPage = sqlite3GlobalConfig.pcache.xFetch(pCache.pCache, pgno, eCreate); } if (null == pPage && 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 = pCache.pSynced; pPg != null && (pPg.nRef != 0 || (pPg.flags & PGHDR_NEED_SYNC) != 0); pPg = pPg.pDirtyPrev ) { ; } pCache.pSynced = pPg; if (null == pPg) { for (pPg = pCache.pDirtyTail; pPg != null && pPg.nRef != 0; pPg = pPg.pDirtyPrev) { ; } } if (pPg != null) { int rc; rc = pCache.xStress(pCache.pStress, pPg); if (rc != SQLITE_OK && rc != SQLITE_BUSY) { return(rc); } } pPage = sqlite3GlobalConfig.pcache.xFetch(pCache.pCache, pgno, 2); } if (pPage != null) { if (null == pPage.pData) { // memset(pPage, 0, sizeof(PgHdr)); pPage.pData = sqlite3Malloc(pCache.szPage);// pPage->pData = (void*)&pPage[1]; //pPage->pExtra = (void*)&((char*)pPage->pData)[pCache->szPage]; //memset(pPage->pExtra, 0, pCache->szExtra); pPage.pCache = pCache; pPage.pgno = pgno; } Debug.Assert(pPage.pCache == pCache); Debug.Assert(pPage.pgno == pgno); //assert(pPage->pData == (void*)&pPage[1]); //assert(pPage->pExtra == (void*)&((char*)&pPage[1])[pCache->szPage]); if (0 == pPage.nRef) { pCache.nRef++; } pPage.nRef++; if (pgno == 1) { pCache.pPage1 = pPage; } } ppPage = pPage; return((pPage == null && eCreate != 0) ? SQLITE_NOMEM : SQLITE_OK); }
/* ** Drop every cache entry whose page number is greater than "pgno". The ** caller must ensure that there are no outstanding references to any pages ** other than page 1 with a page number greater than pgno. ** ** If there is a reference to page 1 and the pgno parameter passed to this ** function is 0, then the data area associated with page 1 is zeroed, but ** the page object is not dropped. */ static void sqlite3PcacheTruncate( PCache pCache, u32 pgno ) { if ( pCache.pCache != null ) { PgHdr p; PgHdr pNext; for ( p = pCache.pDirty ; p != null ; p = pNext ) { pNext = p.pDirtyNext; if ( p.pgno > pgno ) { Debug.Assert( ( p.flags & PGHDR_DIRTY ) != 0 ); sqlite3PcacheMakeClean( p ); } } if ( pgno == 0 && pCache.pPage1 != null ) { pCache.pPage1.pData = new byte[pCache.szPage];// memset( pCache.pPage1.pData, 0, pCache.szPage ); pgno = 1; } sqlite3GlobalConfig.pcache.xTruncate( pCache.pCache, pgno + 1 ); } }
/* ** Set the suggested cache-size value. */ static void sqlite3PcacheSetCachesize( PCache pCache, int mxPage ) { pCache.nMax = mxPage; if ( pCache.pCache != null ) { sqlite3GlobalConfig.pcache.xCachesize( pCache.pCache, mxPage ); } }
/* ** Change the page size for PCache object. The caller must ensure that there ** are no outstanding page references when this function is called. */ static void sqlite3PcacheSetPageSize( PCache pCache, int szPage ) { Debug.Assert( pCache.nRef == 0 && pCache.pDirty == null ); if ( pCache.pCache != null ) { sqlite3GlobalConfig.pcache.xDestroy( ref pCache.pCache ); pCache.pCache = null; } pCache.szPage = szPage; }
/* ** Return the total number of referenced pages held by the cache. */ static int sqlite3PcacheRefCount( PCache pCache ) { return pCache.nRef; }
/* ** Try to obtain a page from the cache. */ static int sqlite3PcacheFetch( PCache pCache, /* Obtain the page from this cache */ u32 pgno, /* Page number to obtain */ int createFlag, /* If true, create page if it does not exist already */ ref PgHdr ppPage /* Write the page here */ ) { PgHdr pPage = null; int eCreate; Debug.Assert( pCache != null ); Debug.Assert( createFlag == 1 || createFlag == 0 ); Debug.Assert( pgno > 0 ); /* If the pluggable cache (sqlite3_pcache*) has not been allocated, ** allocate it now. */ if ( null == pCache.pCache && createFlag != 0 ) { sqlite3_pcache p; int nByte; nByte = pCache.szPage + pCache.szExtra + 0;// sizeof( PgHdr ); p = sqlite3GlobalConfig.pcache.xCreate( nByte, pCache.bPurgeable ); //if ( null == p ) //{ // return SQLITE_NOMEM; //} sqlite3GlobalConfig.pcache.xCachesize( p, pCache.nMax ); pCache.pCache = p; } eCreate = createFlag * ( 1 + ( ( !pCache.bPurgeable || null == pCache.pDirty ) ? 1 : 0 ) ); if ( pCache.pCache != null ) { pPage = sqlite3GlobalConfig.pcache.xFetch( pCache.pCache, pgno, eCreate ); } if ( null == pPage && 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 = pCache.pSynced; pPg != null && ( pPg.nRef != 0 || ( pPg.flags & PGHDR_NEED_SYNC ) != 0 ); pPg = pPg.pDirtyPrev ) ; pCache.pSynced = pPg; if ( null == pPg ) { for ( pPg = pCache.pDirtyTail; pPg != null && pPg.nRef != 0; pPg = pPg.pDirtyPrev ) ; } if ( pPg != null ) { int rc; #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 rc = pCache.xStress( pCache.pStress, pPg ); if ( rc != SQLITE_OK && rc != SQLITE_BUSY ) { return rc; } } pPage = sqlite3GlobalConfig.pcache.xFetch( pCache.pCache, pgno, 2 ); } if ( pPage != null ) { if ( null == pPage.pData ) { // memset(pPage, 0, sizeof(PgHdr)); pPage.pData = sqlite3Malloc( pCache.szPage );// pPage->pData = (void*)&pPage[1]; //pPage->pExtra = (void*)&((char*)pPage->pData)[pCache->szPage]; //memset(pPage->pExtra, 0, pCache->szExtra); pPage.pCache = pCache; pPage.pgno = pgno; } Debug.Assert( pPage.pCache == pCache ); Debug.Assert( pPage.pgno == pgno ); //assert(pPage->pData == (void*)&pPage[1]); //assert(pPage->pExtra == (void*)&((char*)&pPage[1])[pCache->szPage]); if ( 0 == pPage.nRef ) { pCache.nRef++; } pPage.nRef++; if ( pgno == 1 ) { pCache.pPage1 = pPage; } } ppPage = pPage; return ( pPage == null && eCreate != 0 ) ? SQLITE_NOMEM : SQLITE_OK; }
/* ** Get the suggested cache-size value. */ static int sqlite3PcacheGetCachesize( PCache pCache ) { return pCache.nMax; }
/* ** Return the total number of referenced pages held by the cache. */ static int sqlite3PcacheRefCount(PCache pCache) { return(pCache.nRef); }
/* ** Discard the contents of the cache. */ static void sqlite3PcacheClear(PCache pCache) { sqlite3PcacheTruncate(pCache, 0); }