dictresize(): Rebuild small tables if there are any dummies, not just if

they're entirely full.  Not a question of correctness, but of temporarily
misplaced common sense.
This commit is contained in:
Tim Peters 2001-05-24 16:26:40 +00:00
parent 0c6010be75
commit f8a548c23c
1 changed files with 11 additions and 7 deletions

View File

@ -427,16 +427,20 @@ dictresize(dictobject *mp, int minused)
is_oldtable_malloced = oldtable != mp->ma_smalltable; is_oldtable_malloced = oldtable != mp->ma_smalltable;
if (newsize == MINSIZE) { if (newsize == MINSIZE) {
/* Either a large table is shrinking, or we can't get any /* A large table is shrinking, or we can't get any smaller. */
smaller. */
newtable = mp->ma_smalltable; newtable = mp->ma_smalltable;
if (newtable == oldtable) { if (newtable == oldtable) {
if (mp->ma_fill < mp->ma_size) if (mp->ma_fill == mp->ma_used) {
/* No dummies, so no point doing anything. */
return 0; return 0;
/* The small table is entirely full. We're not }
going to resise it, but need to rebuild it /* We're not going to resize it, but rebuild the
anyway to purge old dummy entries. */ table anyway to purge old dummy entries.
assert(mp->ma_fill > mp->ma_used); /* a dummy exists */ Subtle: This is *necessary* if fill==size,
as lookdict needs at least one virgin slot to
terminate failing searches. If fill < size, it's
merely desirable, as dummies slow searches. */
assert(mp->ma_fill > mp->ma_used);
memcpy(small_copy, oldtable, sizeof(small_copy)); memcpy(small_copy, oldtable, sizeof(small_copy));
oldtable = small_copy; oldtable = small_copy;
} }