/* ** Record in the column cache that a particular column from a ** particular table is stored in a particular register. */ static void sqlite3ExprCacheStore( Parse pParse, int iTab, int iCol, int iReg ) { int i; int minLru; int idxLru; yColCache p = new yColCache(); Debug.Assert( iReg > 0 ); /* Register numbers are always positive */ Debug.Assert( iCol >= -1 && iCol < 32768 ); /* Finite column numbers */ /* The SQLITE_ColumnCache flag disables the column cache. This is used ** for testing only - to verify that SQLite always gets the same answer ** with and without the column cache. */ if ( ( pParse.db.flags & SQLITE_ColumnCache ) != 0 ) return; /* First replace any existing entry. ** ** Actually, the way the column cache is currently used, we are guaranteed ** that the object will never already be in cache. Verify this guarantee. */ #if !NDEBUG for ( i = 0; i < SQLITE_N_COLCACHE; i++ )//p=pParse.aColCache... p++) { #if FALSE //* This code wold remove the entry from the cache if it existed */ p = pParse.aColCache[i]; if ( p.iReg != 0 && p.iTable == iTab && p.iColumn == iCol ) { cacheEntryClear( pParse, p ); p.iLevel = pParse.iCacheLevel; p.iReg = iReg; p.lru = pParse.iCacheCnt++; return; } #endif Debug.Assert( p.iReg == 0 || p.iTable != iTab || p.iColumn != iCol ); } #endif /* Find an empty slot and replace it */ for ( i = 0; i < SQLITE_N_COLCACHE; i++ )//p=pParse.aColCache... p++) { p = pParse.aColCache[i]; if ( p.iReg == 0 ) { p.iLevel = pParse.iCacheLevel; p.iTable = iTab; p.iColumn = iCol; p.iReg = iReg; p.tempReg = 0; p.lru = pParse.iCacheCnt++; return; } } /* Replace the last recently used */ minLru = 0x7fffffff; idxLru = -1; for ( i = 0; i < SQLITE_N_COLCACHE; i++ )//p=pParse.aColCache..., p++) { p = pParse.aColCache[i]; if ( p.lru < minLru ) { idxLru = i; minLru = p.lru; } } if ( ALWAYS( idxLru >= 0 ) ) { p = pParse.aColCache[idxLru]; p.iLevel = pParse.iCacheLevel; p.iTable = iTab; p.iColumn = iCol; p.iReg = iReg; p.tempReg = 0; p.lru = pParse.iCacheCnt++; return; } }
/* ** Clear a cache entry. */ static void cacheEntryClear( Parse pParse, yColCache p ) { if ( p.tempReg != 0 ) { if ( pParse.nTempReg < ArraySize( pParse.aTempReg ) ) { pParse.aTempReg[pParse.nTempReg++] = p.iReg; } p.tempReg = 0; } }