#define PERL_IN_HV_C
#include "perl.h"
-#define HV_MAX_LENGTH_BEFORE_SPLIT 4
-
STATIC HE*
S_new_he(pTHX)
{
}
else
HeKFLAGS(entry) = flags;
- if (flags & HVhek_ENABLEHVKFLAGS)
+ if (flags)
HvHASKFLAGS_on(hv);
}
if (flags & HVhek_FREEKEY)
}
else
HeKFLAGS(entry) = flags;
- if (flags & HVhek_ENABLEHVKFLAGS)
+ if (flags)
HvHASKFLAGS_on(hv);
}
if (key != keysave)
register U32 hash, int flags)
{
register XPVHV* xhv;
- register U32 n_links;
+ register I32 i;
register HE *entry;
register HE **oentry;
/* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */
oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
+ i = 1;
- n_links = 0;
-
- for (entry = *oentry; entry; ++n_links, entry = HeNEXT(entry)) {
+ for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
if (HeKLEN(entry) != (I32)klen)
*oentry = entry;
xhv->xhv_keys++; /* HvKEYS(hv)++ */
- if (!n_links) { /* initial entry? */
+ if (i) { /* initial entry? */
xhv->xhv_fill++; /* HvFILL(hv)++ */
- } else if ((n_links > HV_MAX_LENGTH_BEFORE_SPLIT)
- && (!HvREHASH(hv)
- || (xhv->xhv_keys > (IV)xhv->xhv_max))) {
- /* Use the old HvKEYS(hv) > HvMAX(hv) condition to limit bucket
- splits on a rehashed hash, as we're not going to split it again,
- and if someone is lucky (evil) enough to get all the keys in one
- list they could exhaust our memory as we repeatedly double the
- number of buckets on every entry. Linear search feels a less worse
- thing to do. */
+ } else if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */) {
hsplit(hv);
}
XPVHV* xhv;
char *key;
STRLEN klen;
- U32 n_links;
+ I32 i;
HE *entry;
HE **oentry;
bool is_utf8;
/* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */
oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
- n_links = 0;
+ i = 1;
entry = *oentry;
- for (; entry; ++n_links, entry = HeNEXT(entry)) {
+ for (; entry; i=0, entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
if (HeKLEN(entry) != (I32)klen)
*oentry = entry;
xhv->xhv_keys++; /* HvKEYS(hv)++ */
- if (!n_links) { /* initial entry? */
+ if (i) { /* initial entry? */
xhv->xhv_fill++; /* HvFILL(hv)++ */
- } else if ((xhv->xhv_keys > (IV)xhv->xhv_max)
- || ((n_links > HV_MAX_LENGTH_BEFORE_SPLIT) && !HvREHASH(hv))) {
- /* Use only the old HvKEYS(hv) > HvMAX(hv) condition to limit bucket
- splits on a rehashed hash, as we're not going to split it again,
- and if someone is lucky (evil) enough to get all the keys in one
- list they could exhaust our memory as we repeatedly double the
- number of buckets on every entry. Linear search feels a less worse
- thing to do. */
- hsplit(hv);
+ } else if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */) {
+ hsplit(hv);
}
return entry;
/* Pick your policy for "hashing isn't working" here: */
- if (longest_chain <= HV_MAX_LENGTH_BEFORE_SPLIT /* split worked? */
+ if (longest_chain < 8 || longest_chain * 2 < HvTOTALKEYS(hv)
|| HvREHASH(hv)) {
return;
}
xhv->xhv_fill = 0;
HvSHAREKEYS_off(hv);
HvREHASH_on(hv);
+ HvHASKFLAGS_on(hv);
aep = (HE **) xhv->xhv_array;
if (!(Svp = hv_fetch(PL_strtab, str, len, FALSE)))
hv_store(PL_strtab, str, len, Nullsv, hash);
-
- Can't rehash the shared string table, so not sure if it's worth
- counting the number of entries in the linked list
*/
xhv = (XPVHV*)SvANY(PL_strtab);
/* assert(xhv_array != 0) */
* is utf8 (including 8 bit keys that were entered as utf8, and need upgrading
* when retrieved during iteration. It may still be set when there are no longer
* any utf8 keys.
- * See HVhek_ENABLEHVKFLAGS for the trigger.
*/
#define HvHASKFLAGS(hv) (SvFLAGS(hv) & SVphv_HASKFLAGS)
#define HvHASKFLAGS_on(hv) (SvFLAGS(hv) |= SVphv_HASKFLAGS)
* (may change, but Storable is a core module) */
#define HVhek_MASK 0xFF
-/* Which flags enable HvHASKFLAGS? Somewhat a hack on a hack, as
- HVhek_REHASH is only needed because the rehash flag has to be duplicated
- into all keys as hv_iternext has no access to the hash flags. At this
- point Storable's tests get upset, because sometimes hashes are "keyed"
- and sometimes not, depending on the order of data insertion, and whether
- it triggered rehashing. So currently HVhek_REHAS is exempt.
-*/
-
-#define HVhek_ENABLEHVKFLAGS (HVhek_MASK - HVhek_REHASH)
-
#define HEK_UTF8(hek) (HEK_FLAGS(hek) & HVhek_UTF8)
#define HEK_UTF8_on(hek) (HEK_FLAGS(hek) |= HVhek_UTF8)
#define HEK_UTF8_off(hek) (HEK_FLAGS(hek) &= ~HVhek_UTF8)