xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
if (!counter) { /* initial entry? */
- xhv->xhv_fill++; /* HvFILL(hv)++ */
} else if (xhv->xhv_keys > (IV)xhv->xhv_max) {
hsplit(hv);
} else if(!HvREHASH(hv)) {
HvPLACEHOLDERS(hv)++;
} else {
*oentry = HeNEXT(entry);
- if(!*first_entry) {
- xhv->xhv_fill--; /* HvFILL(hv)-- */
- }
if (SvOOK(hv) && entry == HvAUX(hv)->xhv_eiter /* HvEITER(hv) */)
HvLAZYDEL_on(hv);
else
if ((HeHASH(entry) & newsize) != (U32)i) {
*oentry = HeNEXT(entry);
HeNEXT(entry) = *bep;
- if (!*bep)
- xhv->xhv_fill++; /* HvFILL(hv)++ */
*bep = entry;
right_length++;
continue;
left_length++;
}
}
- if (!*aep) /* everything moved */
- xhv->xhv_fill--; /* HvFILL(hv)-- */
/* I think we don't actually need to keep track of the longest length,
merely flag if anything is too long. But for the moment while
developing this code I'll track it. */
was_shared = HvSHAREKEYS(hv);
- xhv->xhv_fill = 0;
HvSHAREKEYS_off(hv);
HvREHASH_on(hv);
/* Copy oentry to the correct new chain. */
bep = ((HE**)a) + (hash & (I32) xhv->xhv_max);
- if (!*bep)
- xhv->xhv_fill++; /* HvFILL(hv)++ */
HeNEXT(entry) = *bep;
*bep = entry;
if (j != i) {
j -= i;
*oentry = HeNEXT(entry);
- if (!(HeNEXT(entry) = aep[j]))
- xhv->xhv_fill++; /* HvFILL(hv)++ */
+ HeNEXT(entry) = aep[j];
aep[j] = entry;
continue;
}
else
oentry = &HeNEXT(entry);
}
- if (!*aep) /* everything moved */
- xhv->xhv_fill--; /* HvFILL(hv)-- */
}
}
}
HvMAX(hv) = hv_max;
- HvFILL(hv) = HvFILL(ohv);
HvTOTALKEYS(hv) = HvTOTALKEYS(ohv);
HvARRAY(hv) = ents;
} /* not magical */
while ((entry = *oentry)) {
if (HeVAL(entry) == &PL_sv_placeholder) {
*oentry = HeNEXT(entry);
- if (first && !*oentry)
- HvFILL(hv)--; /* This linked list is now empty. */
if (entry == HvEITER_get(hv))
HvLAZYDEL_on(hv);
else
/* make everyone else think the array is empty, so that the destructors
* called for freed entries can't recusively mess with us */
HvARRAY(hv) = NULL;
- HvFILL(hv) = 0;
((XPVHV*) SvANY(hv))->xhv_keys = 0;
mg_clear(MUTABLE_SV(hv));
}
+/*
+=for apidoc hv_fill
+
+Returns the number of hash buckets that happen to be in use. This function is
+wrapped by the macro C<HvFILL>.
+
+Previously this value was stored in the HV structure, rather than being
+calculated on demand.
+
+=cut
+*/
+
+STRLEN
+Perl_hv_fill(pTHX_ HV const *const hv)
+{
+ STRLEN count = 0;
+ HE **ents = HvARRAY(hv);
+
+ PERL_ARGS_ASSERT_HV_FILL;
+
+ if (ents) {
+ HE *const *const end = ents + HvMAX(hv);
+
+ do {
+ if (*ents)
+ ++count;
+ } while (++ents <= end);
+ }
+ return count;
+}
+
static struct xpvhv_aux*
S_hv_auxinit(HV *hv) {
struct xpvhv_aux *iter;
if (entry) {
if (--entry->he_valu.hent_refcount == 0) {
*oentry = HeNEXT(entry);
- if (!*first) {
- /* There are now no entries in our slot. */
- xhv->xhv_fill--; /* HvFILL(hv)-- */
- }
Safefree(entry);
xhv->xhv_keys--; /* HvTOTALKEYS(hv)-- */
}
xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */
if (!next) { /* initial entry? */
- xhv->xhv_fill++; /* HvFILL(hv)++ */
} else if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */) {
hsplit(PL_strtab);
}
/* Link it into the chain. */
HeNEXT(entry) = *oentry;
- if (!HeNEXT(entry)) {
- /* initial entry. */
- HvFILL(hv)++;
- }
*oentry = entry;
HvTOTALKEYS(hv)++;