/* Find existing tile, make a new tile, or if we have a full set of tiles, * reuse LRU. */ static Tile * tile_find( Read *read, REGION *in, int x, int y ) { Tile *tile; int oldest; GSList *p; /* In cache already? */ if( (tile = tile_search( read, x, y )) ) { tile_touch( tile ); return( tile ); } /* Cache not full? */ if( read->max_tiles == -1 || read->ntiles < read->max_tiles ) { if( !(tile = tile_new( read )) || tile_move( tile, x, y ) || tile_fill( tile, in ) ) return( NULL ); return( tile ); } /* Reuse an old one. */ oldest = read->time; tile = NULL; for( p = read->cache; p; p = p->next ) { Tile *t = (Tile *) p->data; if( t->time < oldest ) { oldest = t->time; tile = t; } } g_assert( tile ); #ifdef DEBUG printf( "im_tile_cache: reusing tile %d x %d\n", tile->x, tile->y ); #endif /*DEBUG*/ if( tile_move( tile, x, y ) || tile_fill( tile, in ) ) return( NULL ); return( tile ); }
/* Find existing tile, make a new tile, or if we have a full set of tiles, * reuse LRU. */ static Tile * tile_find( VipsTileCache *cache, VipsRegion *in, int x, int y ) { Tile *tile; int oldest, topmost; GSList *p; /* In cache already? */ if( (tile = tile_search( cache, x, y )) ) { tile_touch( tile ); return( tile ); } /* VipsTileCache not full? */ if( cache->max_tiles == -1 || cache->ntiles < cache->max_tiles ) { if( !(tile = tile_new( cache )) || tile_move( tile, x, y ) || tile_fill( tile, in ) ) return( NULL ); return( tile ); } /* Reuse an old one. */ switch( cache->strategy ) { case VIPS_CACHE_RANDOM: oldest = cache->time; tile = NULL; for( p = cache->tiles; p; p = p->next ) { Tile *t = (Tile *) p->data; if( t->time < oldest ) { oldest = t->time; tile = t; } } break; case VIPS_CACHE_SEQUENTIAL: topmost = cache->in->Ysize; tile = NULL; for( p = cache->tiles; p; p = p->next ) { Tile *t = (Tile *) p->data; if( t->y < topmost ) { topmost = t->y; tile = t; } } break; default: g_assert( 0 ); } g_assert( tile ); VIPS_DEBUG_MSG( "tilecache: reusing tile %d x %d\n", tile->x, tile->y ); if( tile_move( tile, x, y ) || tile_fill( tile, in ) ) return( NULL ); return( tile ); }