Correct CODE block declaration
[p5sagit/p5-mst-13.2.git] / hv.c
diff --git a/hv.c b/hv.c
index 27833f9..d9cbe52 100644 (file)
--- a/hv.c
+++ b/hv.c
 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;