@@ -245,30 +245,6 @@ vips_tile_search(VipsBlockCache *cache, int x, int y)
245
245
return tile ;
246
246
}
247
247
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
-
272
248
/* Find existing tile, make a new tile, or if we have a full set of tiles,
273
249
* reuse one.
274
250
*/
@@ -300,15 +276,8 @@ vips_tile_find(VipsBlockCache *cache, int x, int y)
300
276
/* Reuse an old one, if there are any. We just peek the tile pointer,
301
277
* it is removed from the recycle list later on _ref.
302
278
*/
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 );
312
281
313
282
if (!tile ) {
314
283
/* There are no tiles we can reuse -- we have to make another
@@ -500,6 +469,21 @@ typedef VipsBlockCacheClass VipsTileCacheClass;
500
469
501
470
G_DEFINE_TYPE (VipsTileCache , vips_tile_cache , VIPS_TYPE_BLOCK_CACHE );
502
471
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
+
503
487
static void
504
488
vips_tile_unref (VipsTile * tile )
505
489
{
@@ -508,12 +492,19 @@ vips_tile_unref(VipsTile *tile)
508
492
tile -> ref_count -= 1 ;
509
493
510
494
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
- */
514
495
g_assert (!g_queue_find (tile -> cache -> recycle , tile ));
515
496
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 );
517
508
}
518
509
}
519
510
0 commit comments