X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.c;h=d9cbe52337fe12a016722261d27fe5d9e6eba4c5;hb=f13e1b2f9edd0ad9259bea67c343cb00d1d5e9e3;hp=27833f91d250de21d943c5fce16894d1a4be2a60;hpb=8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.c b/hv.c index 27833f9..d9cbe52 100644 --- a/hv.c +++ b/hv.c @@ -17,6 +17,44 @@ static void hsplit _((HV *hv)); static void hfreeentries _((HV *hv)); +static HE* more_he(); + +static HE* +new_he() +{ + HE* he; + if (he_root) { + he = he_root; + he_root = (HE*)he->hent_next; + return he; + } + return more_he(); +} + +static void +del_he(p) +HE* p; +{ + p->hent_next = (HE*)he_root; + he_root = p; +} + +static HE* +more_he() +{ + register HE* he; + register HE* heend; + he_root = (HE*)safemalloc(1008); + he = he_root; + heend = &he[1008 / sizeof(HE) - 1]; + while (he < heend) { + he->hent_next = (HE*)(he + 1); + he++; + } + he->hent_next = 0; + return new_he(); +} + SV** hv_fetch(hv,key,klen,lval) HV *hv; @@ -142,8 +180,8 @@ register U32 hash; entry->hent_val = val; return &entry->hent_val; } - New(501,entry, 1, HE); + entry = new_he(); entry->hent_klen = klen; entry->hent_key = savepvn(key,klen); entry->hent_val = val; @@ -282,10 +320,33 @@ HV *hv; register HE **b; register HE *entry; register HE **oentry; +#ifndef STRANGE_MALLOC + I32 tmp; +#endif a = (HE**)xhv->xhv_array; nomemok = TRUE; +#ifdef STRANGE_MALLOC Renew(a, newsize, HE*); +#else + i = newsize * sizeof(HE*); +#define MALLOC_OVERHEAD 16 + tmp = MALLOC_OVERHEAD; + while (tmp - MALLOC_OVERHEAD < i) + tmp += tmp; + tmp -= MALLOC_OVERHEAD; + tmp /= sizeof(HE*); + assert(tmp >= newsize); + New(2,a, tmp, HE*); + Copy(xhv->xhv_array, a, oldsize, HE*); + if (oldsize >= 64 && !nice_chunk) { + nice_chunk = (char*)xhv->xhv_array; + nice_chunk_size = oldsize * sizeof(HE*) * 2 - MALLOC_OVERHEAD; + } + else + Safefree(xhv->xhv_array); +#endif + nomemok = FALSE; Zero(&a[oldsize], oldsize, HE*); /* zero 2nd half*/ xhv->xhv_max = --newsize; @@ -338,7 +399,7 @@ register HE *hent; return; SvREFCNT_dec(hent->hent_val); Safefree(hent->hent_key); - Safefree(hent); + del_he(hent); } void @@ -349,7 +410,7 @@ register HE *hent; return; sv_2mortal(hent->hent_val); /* free between statements */ Safefree(hent->hent_key); - Safefree(hent); + del_he(hent); } void @@ -461,8 +522,8 @@ HV *hv; entry->hent_key = 0; } else { - Newz(504,entry, 1, HE); - xhv->xhv_eiter = entry; + xhv->xhv_eiter = entry = new_he(); + Zero(entry, 1, HE); } magic_nextpack((SV*) hv,mg,key); if (SvOK(key)) { @@ -475,14 +536,13 @@ HV *hv; } if (entry->hent_val) SvREFCNT_dec(entry->hent_val); - Safefree(entry); + del_he(entry); xhv->xhv_eiter = Null(HE*); return Null(HE*); } if (!xhv->xhv_array) - entry = Null(HE*); - else + Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char); do { if (entry) entry = entry->hent_next;