Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a23d355

Browse files
committed
Avoid searching the recycle list for the topmost tile
Instead, ensure we insert the tiles sorted.
1 parent abbe955 commit a23d355

File tree

1 file changed

+28
-37
lines changed

1 file changed

+28
-37
lines changed

libvips/conversion/tilecache.c

+28-37
Original file line numberDiff line numberDiff line change
@@ -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

501470
G_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+
503487
static void
504488
vips_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

Comments
 (0)