@@ -245,30 +245,6 @@ vips_tile_search(VipsBlockCache *cache, int x, int y)
245245 return tile ;
246246}
247247
248- static void
249- vips_tile_find_is_topper (gpointer element , gpointer user_data )
250- {
251- VipsTile * this = (VipsTile * ) element ;
252- VipsTile * * best = (VipsTile * * ) user_data ;
253-
254- if (!* best ||
255- this -> pos .top < (* best )-> pos .top )
256- * best = this ;
257- }
258-
259- /* Search the recycle list for the topmost tile.
260- */
261- static VipsTile *
262- vips_tile_find_topmost (GQueue * recycle )
263- {
264- VipsTile * tile ;
265-
266- tile = NULL ;
267- g_queue_foreach (recycle , vips_tile_find_is_topper , & tile );
268-
269- return tile ;
270- }
271-
272248/* Find existing tile, make a new tile, or if we have a full set of tiles,
273249 * reuse one.
274250 */
@@ -300,15 +276,8 @@ vips_tile_find(VipsBlockCache *cache, int x, int y)
300276 /* Reuse an old one, if there are any. We just peek the tile pointer,
301277 * it is removed from the recycle list later on _ref.
302278 */
303- if (cache -> recycle ) {
304- if (cache -> access == VIPS_ACCESS_RANDOM )
305- tile = g_queue_peek_head (cache -> recycle );
306- else
307- /* This is slower :( We have to search the recycle
308- * queue.
309- */
310- tile = vips_tile_find_topmost (cache -> recycle );
311- }
279+ if (cache -> recycle )
280+ tile = g_queue_peek_head (cache -> recycle );
312281
313282 if (!tile ) {
314283 /* There are no tiles we can reuse -- we have to make another
@@ -500,6 +469,21 @@ typedef VipsBlockCacheClass VipsTileCacheClass;
500469
501470G_DEFINE_TYPE (VipsTileCache , vips_tile_cache , VIPS_TYPE_BLOCK_CACHE );
502471
472+ static int
473+ vips_tile_compare_top (gconstpointer a , gconstpointer b ,
474+ gpointer user_data )
475+ {
476+ VipsTile * left = (VipsTile * ) a ;
477+ VipsTile * right = (VipsTile * ) b ;
478+
479+ if (left -> pos .top > right -> pos .top )
480+ return 1 ;
481+ else if (left -> pos .top == right -> pos .top )
482+ return 0 ;
483+ else
484+ return -1 ;
485+ }
486+
503487static void
504488vips_tile_unref (VipsTile * tile )
505489{
@@ -508,12 +492,19 @@ vips_tile_unref(VipsTile *tile)
508492 tile -> ref_count -= 1 ;
509493
510494 if (tile -> ref_count == 0 ) {
511- /* Place at the end of the recycle queue. We pop from the
512- * front when selecting an unused tile for reuse.
513- */
514495 g_assert (!g_queue_find (tile -> cache -> recycle , tile ));
515496
516- g_queue_push_tail (tile -> cache -> recycle , tile );
497+ if (tile -> cache -> access == VIPS_ACCESS_RANDOM )
498+ /* Place at the end of the recycle queue. We pop from
499+ * the front when selecting an unused tile for reuse.
500+ */
501+ g_queue_push_tail (tile -> cache -> recycle , tile );
502+ else
503+ /* This is slower :( We need to make sure we have a
504+ * sorted queue.
505+ */
506+ g_queue_insert_sorted (tile -> cache -> recycle , tile ,
507+ (GCompareDataFunc ) vips_tile_compare_top , NULL );
517508 }
518509}
519510
0 commit comments