tag/TagPool: optimize _dup_item()

When a reference counter is at its limit, don't allocate a new
TagPoolSlot - that would result in many TagPoolSlot instances with
ref==1.  This in turn would make the linked list very very large,
which means quadratic runtime for many operations.
This commit is contained in:
Max Kellermann 2016-03-14 13:08:04 +01:00
parent f1285a6dfd
commit a3afd5178c
2 changed files with 4 additions and 7 deletions

1
NEWS
View File

@ -4,6 +4,7 @@ ver 0.19.14 (not yet released)
- opus: limit tag size to 64 kB - opus: limit tag size to 64 kB
* archive * archive
- iso9660: fix buffer overflow - iso9660: fix buffer overflow
* fix quadratic runtime bug in the tag pool
* fix build failures on non-glibc builds due to constexpr Mutex * fix build failures on non-glibc builds due to constexpr Mutex
ver 0.19.13 (2016/02/23) ver 0.19.13 (2016/02/23)

View File

@ -144,14 +144,10 @@ tag_pool_dup_item(TagItem *item)
return item; return item;
} else { } else {
/* the reference counter overflows above MAX_REF; /* the reference counter overflows above MAX_REF;
duplicate the item, and start with 1 */ obtain a reference to a different TagPoolSlot which
isn't yet "full" */
size_t length = strlen(item->value); size_t length = strlen(item->value);
auto slot_p = tag_value_slot_p(item->type, return tag_pool_get_item(item->type, item->value, length);
item->value, length);
slot = TagPoolSlot::Create(*slot_p, item->type,
item->value, strlen(item->value));
*slot_p = slot;
return &slot->item;
} }
} }