[asperl] initial merge of latest win32 branch into ASPerl
[p5sagit/p5-mst-13.2.git] / hv.c
1 /*    hv.c
2  *
3  *    Copyright (c) 1991-1997, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * "I sit beside the fire and think of all that I have seen."  --Bilbo
12  */
13
14 #include "EXTERN.h"
15 #include "perl.h"
16
17 static void hv_magic_check _((HV *hv, bool *needs_copy, bool *needs_store));
18 #ifndef PERL_OBJECT
19 static void hsplit _((HV *hv));
20 static void hfreeentries _((HV *hv));
21 static HE* more_he _((void));
22 #endif
23
24 STATIC HE*
25 new_he(void)
26 {
27     HE* he;
28     if (he_root) {
29         he = he_root;
30         he_root = HeNEXT(he);
31         return he;
32     }
33     return more_he();
34 }
35
36 STATIC void
37 del_he(HE *p)
38 {
39     HeNEXT(p) = (HE*)he_root;
40     he_root = p;
41 }
42
43 STATIC HE*
44 more_he(void)
45 {
46     register HE* he;
47     register HE* heend;
48     he_root = (HE*)safemalloc(1008);
49     he = he_root;
50     heend = &he[1008 / sizeof(HE) - 1];
51     while (he < heend) {
52         HeNEXT(he) = (HE*)(he + 1);
53         he++;
54     }
55     HeNEXT(he) = 0;
56     return new_he();
57 }
58
59 STATIC HEK *
60 save_hek(char *str, I32 len, U32 hash)
61 {
62     char *k;
63     register HEK *hek;
64     
65     New(54, k, HEK_BASESIZE + len + 1, char);
66     hek = (HEK*)k;
67     Copy(str, HEK_KEY(hek), len, char);
68     *(HEK_KEY(hek) + len) = '\0';
69     HEK_LEN(hek) = len;
70     HEK_HASH(hek) = hash;
71     return hek;
72 }
73
74 void
75 unshare_hek(HEK *hek)
76 {
77     unsharepvn(HEK_KEY(hek),HEK_LEN(hek),HEK_HASH(hek));
78 }
79
80 /* (klen == HEf_SVKEY) is special for MAGICAL hv entries, meaning key slot
81  * contains an SV* */
82
83 SV**
84 hv_fetch(HV *hv, char *key, U32 klen, I32 lval)
85 {
86     register XPVHV* xhv;
87     register U32 hash;
88     register HE *entry;
89     SV *sv;
90
91     if (!hv)
92         return 0;
93
94     if (SvRMAGICAL(hv)) {
95         if (mg_find((SV*)hv,'P')) {
96             dTHR;
97             sv = sv_newmortal();
98             mg_copy((SV*)hv, sv, key, klen);
99             Sv = sv;
100             return &Sv;
101         }
102 #ifdef ENV_IS_CASELESS
103         else if (mg_find((SV*)hv,'E')) {
104             U32 i;
105             for (i = 0; i < klen; ++i)
106                 if (isLOWER(key[i])) {
107                     char *nkey = strupr(SvPVX(sv_2mortal(newSVpv(key,klen))));
108                     SV **ret = hv_fetch(hv, nkey, klen, 0);
109                     if (!ret && lval)
110                         ret = hv_store(hv, key, klen, NEWSV(61,0), 0);
111                     return ret;
112                 }
113         }
114 #endif
115     }
116
117     xhv = (XPVHV*)SvANY(hv);
118     if (!xhv->xhv_array) {
119         if (lval 
120 #ifdef DYNAMIC_ENV_FETCH  /* if it's an %ENV lookup, we may get it on the fly */
121                  || (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME))
122 #endif
123                                                                   )
124             Newz(503,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char);
125         else
126             return 0;
127     }
128
129     PERL_HASH(hash, key, klen);
130
131     entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
132     for (; entry; entry = HeNEXT(entry)) {
133         if (HeHASH(entry) != hash)              /* strings can't be equal */
134             continue;
135         if (HeKLEN(entry) != klen)
136             continue;
137         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
138             continue;
139         return &HeVAL(entry);
140     }
141 #ifdef DYNAMIC_ENV_FETCH  /* %ENV lookup?  If so, try to fetch the value now */
142     if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
143       char *gotenv;
144
145       if ((gotenv = ENV_getenv(key)) != Nullch) {
146         sv = newSVpv(gotenv,strlen(gotenv));
147         SvTAINTED_on(sv);
148         return hv_store(hv,key,klen,sv,hash);
149       }
150     }
151 #endif
152     if (lval) {         /* gonna assign to this, so it better be there */
153         sv = NEWSV(61,0);
154         return hv_store(hv,key,klen,sv,hash);
155     }
156     return 0;
157 }
158
159 /* returns a HE * structure with the all fields set */
160 /* note that hent_val will be a mortal sv for MAGICAL hashes */
161 HE *
162 hv_fetch_ent(HV *hv, SV *keysv, I32 lval, register U32 hash)
163 {
164     register XPVHV* xhv;
165     register char *key;
166     STRLEN klen;
167     register HE *entry;
168     SV *sv;
169
170     if (!hv)
171         return 0;
172
173     if (SvRMAGICAL(hv)) {
174         if (mg_find((SV*)hv,'P')) {
175             static HE mh;
176
177             sv = sv_newmortal();
178             keysv = sv_2mortal(newSVsv(keysv));
179             mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY);
180             if (!HeKEY_hek(&mh)) {
181                 char *k;
182                 New(54, k, HEK_BASESIZE + sizeof(SV*), char);
183                 HeKEY_hek(&mh) = (HEK*)k;
184             }
185             HeSVKEY_set(&mh, keysv);
186             HeVAL(&mh) = sv;
187             return &mh;
188         }
189 #ifdef ENV_IS_CASELESS
190         else if (mg_find((SV*)hv,'E')) {
191             U32 i;
192             key = SvPV(keysv, klen);
193             for (i = 0; i < klen; ++i)
194                 if (isLOWER(key[i])) {
195                     SV *nkeysv = sv_2mortal(newSVpv(key,klen));
196                     (void)strupr(SvPVX(nkeysv));
197                     entry = hv_fetch_ent(hv, nkeysv, 0, 0);
198                     if (!entry && lval)
199                         entry = hv_store_ent(hv, keysv, NEWSV(61,0), hash);
200                     return entry;
201                 }
202         }
203 #endif
204     }
205
206     xhv = (XPVHV*)SvANY(hv);
207     if (!xhv->xhv_array) {
208         if (lval 
209 #ifdef DYNAMIC_ENV_FETCH  /* if it's an %ENV lookup, we may get it on the fly */
210                  || (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME))
211 #endif
212                                                                   )
213             Newz(503,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char);
214         else
215             return 0;
216     }
217
218     key = SvPV(keysv, klen);
219     
220     if (!hash)
221         PERL_HASH(hash, key, klen);
222
223     entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
224     for (; entry; entry = HeNEXT(entry)) {
225         if (HeHASH(entry) != hash)              /* strings can't be equal */
226             continue;
227         if (HeKLEN(entry) != klen)
228             continue;
229         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
230             continue;
231         return entry;
232     }
233 #ifdef DYNAMIC_ENV_FETCH  /* %ENV lookup?  If so, try to fetch the value now */
234     if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
235       char *gotenv;
236
237       if ((gotenv = ENV_getenv(key)) != Nullch) {
238         sv = newSVpv(gotenv,strlen(gotenv));
239         SvTAINTED_on(sv);
240         return hv_store_ent(hv,keysv,sv,hash);
241       }
242     }
243 #endif
244     if (lval) {         /* gonna assign to this, so it better be there */
245         sv = NEWSV(61,0);
246         return hv_store_ent(hv,keysv,sv,hash);
247     }
248     return 0;
249 }
250
251 static void
252 hv_magic_check (HV *hv, bool *needs_copy, bool *needs_store)
253 {
254     MAGIC *mg = SvMAGIC(hv);
255     *needs_copy = FALSE;
256     *needs_store = TRUE;
257     while (mg) {
258         if (isUPPER(mg->mg_type)) {
259             *needs_copy = TRUE;
260             switch (mg->mg_type) {
261             case 'P':
262             case 'S':
263                 *needs_store = FALSE;
264             }
265         }
266         mg = mg->mg_moremagic;
267     }
268 }
269
270 SV**
271 hv_store(HV *hv, char *key, U32 klen, SV *val, register U32 hash)
272 {
273     register XPVHV* xhv;
274     register I32 i;
275     register HE *entry;
276     register HE **oentry;
277
278     if (!hv)
279         return 0;
280
281     xhv = (XPVHV*)SvANY(hv);
282     if (SvMAGICAL(hv)) {
283         bool needs_copy;
284         bool needs_store;
285         hv_magic_check (hv, &needs_copy, &needs_store);
286         if (needs_copy) {
287             mg_copy((SV*)hv, val, key, klen);
288             if (!xhv->xhv_array && !needs_store)
289                 return 0;
290 #ifdef ENV_IS_CASELESS
291             else if (mg_find((SV*)hv,'E')) {
292                 SV *sv = sv_2mortal(newSVpv(key,klen));
293                 key = strupr(SvPVX(sv));
294                 hash = 0;
295             }
296 #endif
297         }
298     }
299     if (!hash)
300         PERL_HASH(hash, key, klen);
301
302     if (!xhv->xhv_array)
303         Newz(505, xhv->xhv_array, sizeof(HE**) * (xhv->xhv_max + 1), char);
304
305     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
306     i = 1;
307
308     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
309         if (HeHASH(entry) != hash)              /* strings can't be equal */
310             continue;
311         if (HeKLEN(entry) != klen)
312             continue;
313         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
314             continue;
315         SvREFCNT_dec(HeVAL(entry));
316         HeVAL(entry) = val;
317         return &HeVAL(entry);
318     }
319
320     entry = new_he();
321     if (HvSHAREKEYS(hv))
322         HeKEY_hek(entry) = share_hek(key, klen, hash);
323     else                                       /* gotta do the real thing */
324         HeKEY_hek(entry) = save_hek(key, klen, hash);
325     HeVAL(entry) = val;
326     HeNEXT(entry) = *oentry;
327     *oentry = entry;
328
329     xhv->xhv_keys++;
330     if (i) {                            /* initial entry? */
331         ++xhv->xhv_fill;
332         if (xhv->xhv_keys > xhv->xhv_max)
333             hsplit(hv);
334     }
335
336     return &HeVAL(entry);
337 }
338
339 HE *
340 hv_store_ent(HV *hv, SV *keysv, SV *val, register U32 hash)
341 {
342     register XPVHV* xhv;
343     register char *key;
344     STRLEN klen;
345     register I32 i;
346     register HE *entry;
347     register HE **oentry;
348
349     if (!hv)
350         return 0;
351
352     xhv = (XPVHV*)SvANY(hv);
353     if (SvMAGICAL(hv)) {
354         dTHR;
355         bool needs_copy;
356         bool needs_store;
357         hv_magic_check (hv, &needs_copy, &needs_store);
358         if (needs_copy) {
359             bool save_taint = tainted;
360             if (tainting)
361                 tainted = SvTAINTED(keysv);
362             keysv = sv_2mortal(newSVsv(keysv));
363             mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY);
364             TAINT_IF(save_taint);
365             if (!xhv->xhv_array && !needs_store)
366                 return Nullhe;
367 #ifdef ENV_IS_CASELESS
368             else if (mg_find((SV*)hv,'E')) {
369                 key = SvPV(keysv, klen);
370                 keysv = sv_2mortal(newSVpv(key,klen));
371                 (void)strupr(SvPVX(keysv));
372                 hash = 0;
373             }
374 #endif
375         }
376     }
377
378     key = SvPV(keysv, klen);
379
380     if (!hash)
381         PERL_HASH(hash, key, klen);
382
383     if (!xhv->xhv_array)
384         Newz(505, xhv->xhv_array, sizeof(HE**) * (xhv->xhv_max + 1), char);
385
386     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
387     i = 1;
388
389     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
390         if (HeHASH(entry) != hash)              /* strings can't be equal */
391             continue;
392         if (HeKLEN(entry) != klen)
393             continue;
394         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
395             continue;
396         SvREFCNT_dec(HeVAL(entry));
397         HeVAL(entry) = val;
398         return entry;
399     }
400
401     entry = new_he();
402     if (HvSHAREKEYS(hv))
403         HeKEY_hek(entry) = share_hek(key, klen, hash);
404     else                                       /* gotta do the real thing */
405         HeKEY_hek(entry) = save_hek(key, klen, hash);
406     HeVAL(entry) = val;
407     HeNEXT(entry) = *oentry;
408     *oentry = entry;
409
410     xhv->xhv_keys++;
411     if (i) {                            /* initial entry? */
412         ++xhv->xhv_fill;
413         if (xhv->xhv_keys > xhv->xhv_max)
414             hsplit(hv);
415     }
416
417     return entry;
418 }
419
420 SV *
421 hv_delete(HV *hv, char *key, U32 klen, I32 flags)
422 {
423     register XPVHV* xhv;
424     register I32 i;
425     register U32 hash;
426     register HE *entry;
427     register HE **oentry;
428     SV **svp;
429     SV *sv;
430
431     if (!hv)
432         return Nullsv;
433     if (SvRMAGICAL(hv)) {
434         bool needs_copy;
435         bool needs_store;
436         hv_magic_check (hv, &needs_copy, &needs_store);
437
438         if (needs_copy && (svp = hv_fetch(hv, key, klen, TRUE))) {
439             sv = *svp;
440             mg_clear(sv);
441             if (!needs_store) {
442                 if (mg_find(sv, 'p')) {
443                     sv_unmagic(sv, 'p');        /* No longer an element */
444                     return sv;
445                 }
446                 return Nullsv;          /* element cannot be deleted */
447             }
448 #ifdef ENV_IS_CASELESS
449             else if (mg_find((SV*)hv,'E')) {
450                 sv = sv_2mortal(newSVpv(key,klen));
451                 key = strupr(SvPVX(sv));
452             }
453 #endif
454         }
455     }
456     xhv = (XPVHV*)SvANY(hv);
457     if (!xhv->xhv_array)
458         return Nullsv;
459
460     PERL_HASH(hash, key, klen);
461
462     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
463     entry = *oentry;
464     i = 1;
465     for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
466         if (HeHASH(entry) != hash)              /* strings can't be equal */
467             continue;
468         if (HeKLEN(entry) != klen)
469             continue;
470         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
471             continue;
472         *oentry = HeNEXT(entry);
473         if (i && !*oentry)
474             xhv->xhv_fill--;
475         if (flags & G_DISCARD)
476             sv = Nullsv;
477         else
478             sv = sv_mortalcopy(HeVAL(entry));
479         if (entry == xhv->xhv_eiter)
480             HvLAZYDEL_on(hv);
481         else
482             hv_free_ent(hv, entry);
483         --xhv->xhv_keys;
484         return sv;
485     }
486     return Nullsv;
487 }
488
489 SV *
490 hv_delete_ent(HV *hv, SV *keysv, I32 flags, U32 hash)
491 {
492     register XPVHV* xhv;
493     register I32 i;
494     register char *key;
495     STRLEN klen;
496     register HE *entry;
497     register HE **oentry;
498     SV *sv;
499     
500     if (!hv)
501         return Nullsv;
502     if (SvRMAGICAL(hv)) {
503         bool needs_copy;
504         bool needs_store;
505         hv_magic_check (hv, &needs_copy, &needs_store);
506
507         if (needs_copy && (entry = hv_fetch_ent(hv, keysv, TRUE, hash))) {
508             sv = HeVAL(entry);
509             mg_clear(sv);
510             if (!needs_store) {
511                 if (mg_find(sv, 'p')) {
512                     sv_unmagic(sv, 'p');        /* No longer an element */
513                     return sv;
514                 }               
515                 return Nullsv;          /* element cannot be deleted */
516             }
517 #ifdef ENV_IS_CASELESS
518             else if (mg_find((SV*)hv,'E')) {
519                 key = SvPV(keysv, klen);
520                 keysv = sv_2mortal(newSVpv(key,klen));
521                 (void)strupr(SvPVX(keysv));
522                 hash = 0; 
523             }
524 #endif
525         }
526     }
527     xhv = (XPVHV*)SvANY(hv);
528     if (!xhv->xhv_array)
529         return Nullsv;
530
531     key = SvPV(keysv, klen);
532     
533     if (!hash)
534         PERL_HASH(hash, key, klen);
535
536     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
537     entry = *oentry;
538     i = 1;
539     for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
540         if (HeHASH(entry) != hash)              /* strings can't be equal */
541             continue;
542         if (HeKLEN(entry) != klen)
543             continue;
544         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
545             continue;
546         *oentry = HeNEXT(entry);
547         if (i && !*oentry)
548             xhv->xhv_fill--;
549         if (flags & G_DISCARD)
550             sv = Nullsv;
551         else
552             sv = sv_mortalcopy(HeVAL(entry));
553         if (entry == xhv->xhv_eiter)
554             HvLAZYDEL_on(hv);
555         else
556             hv_free_ent(hv, entry);
557         --xhv->xhv_keys;
558         return sv;
559     }
560     return Nullsv;
561 }
562
563 bool
564 hv_exists(HV *hv, char *key, U32 klen)
565 {
566     register XPVHV* xhv;
567     register U32 hash;
568     register HE *entry;
569     SV *sv;
570
571     if (!hv)
572         return 0;
573
574     if (SvRMAGICAL(hv)) {
575         if (mg_find((SV*)hv,'P')) {
576             dTHR;
577             sv = sv_newmortal();
578             mg_copy((SV*)hv, sv, key, klen); 
579             magic_existspack(sv, mg_find(sv, 'p'));
580             return SvTRUE(sv);
581         }
582 #ifdef ENV_IS_CASELESS
583         else if (mg_find((SV*)hv,'E')) {
584             sv = sv_2mortal(newSVpv(key,klen));
585             key = strupr(SvPVX(sv));
586         }
587 #endif
588     }
589
590     xhv = (XPVHV*)SvANY(hv);
591     if (!xhv->xhv_array)
592         return 0; 
593
594     PERL_HASH(hash, key, klen);
595
596     entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
597     for (; entry; entry = HeNEXT(entry)) {
598         if (HeHASH(entry) != hash)              /* strings can't be equal */
599             continue;
600         if (HeKLEN(entry) != klen)
601             continue;
602         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
603             continue;
604         return TRUE;
605     }
606     return FALSE;
607 }
608
609
610 bool
611 hv_exists_ent(HV *hv, SV *keysv, U32 hash)
612 {
613     register XPVHV* xhv;
614     register char *key;
615     STRLEN klen;
616     register HE *entry;
617     SV *sv;
618
619     if (!hv)
620         return 0;
621
622     if (SvRMAGICAL(hv)) {
623         if (mg_find((SV*)hv,'P')) {
624             dTHR;               /* just for SvTRUE */
625             sv = sv_newmortal();
626             keysv = sv_2mortal(newSVsv(keysv));
627             mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY); 
628             magic_existspack(sv, mg_find(sv, 'p'));
629             return SvTRUE(sv);
630         }
631 #ifdef ENV_IS_CASELESS
632         else if (mg_find((SV*)hv,'E')) {
633             key = SvPV(keysv, klen);
634             keysv = sv_2mortal(newSVpv(key,klen));
635             (void)strupr(SvPVX(keysv));
636             hash = 0; 
637         }
638 #endif
639     }
640
641     xhv = (XPVHV*)SvANY(hv);
642     if (!xhv->xhv_array)
643         return 0; 
644
645     key = SvPV(keysv, klen);
646     if (!hash)
647         PERL_HASH(hash, key, klen);
648
649     entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
650     for (; entry; entry = HeNEXT(entry)) {
651         if (HeHASH(entry) != hash)              /* strings can't be equal */
652             continue;
653         if (HeKLEN(entry) != klen)
654             continue;
655         if (memNE(HeKEY(entry),key,klen))       /* is this it? */
656             continue;
657         return TRUE;
658     }
659     return FALSE;
660 }
661
662 STATIC void
663 hsplit(HV *hv)
664 {
665     register XPVHV* xhv = (XPVHV*)SvANY(hv);
666     I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
667     register I32 newsize = oldsize * 2;
668     register I32 i;
669     register HE **a;
670     register HE **b;
671     register HE *entry;
672     register HE **oentry;
673 #ifndef STRANGE_MALLOC
674     I32 tmp;
675 #endif
676
677     a = (HE**)xhv->xhv_array;
678     nomemok = TRUE;
679 #ifdef STRANGE_MALLOC
680     Renew(a, newsize, HE*);
681 #else
682     i = newsize * sizeof(HE*);
683 #define MALLOC_OVERHEAD 16
684     tmp = MALLOC_OVERHEAD;
685     while (tmp - MALLOC_OVERHEAD < i)
686         tmp += tmp;
687     tmp -= MALLOC_OVERHEAD;
688     tmp /= sizeof(HE*);
689     assert(tmp >= newsize);
690     New(2,a, tmp, HE*);
691     Copy(xhv->xhv_array, a, oldsize, HE*);
692     if (oldsize >= 64) {
693         offer_nice_chunk(xhv->xhv_array,
694                          oldsize * sizeof(HE*) * 2 - MALLOC_OVERHEAD);
695     }
696     else
697         Safefree(xhv->xhv_array);
698 #endif
699
700     nomemok = FALSE;
701     Zero(&a[oldsize], oldsize, HE*);            /* zero 2nd half*/
702     xhv->xhv_max = --newsize;
703     xhv->xhv_array = (char*)a;
704
705     for (i=0; i<oldsize; i++,a++) {
706         if (!*a)                                /* non-existent */
707             continue;
708         b = a+oldsize;
709         for (oentry = a, entry = *a; entry; entry = *oentry) {
710             if ((HeHASH(entry) & newsize) != i) {
711                 *oentry = HeNEXT(entry);
712                 HeNEXT(entry) = *b;
713                 if (!*b)
714                     xhv->xhv_fill++;
715                 *b = entry;
716                 continue;
717             }
718             else
719                 oentry = &HeNEXT(entry);
720         }
721         if (!*a)                                /* everything moved */
722             xhv->xhv_fill--;
723     }
724 }
725
726 void
727 hv_ksplit(HV *hv, IV newmax)
728 {
729     register XPVHV* xhv = (XPVHV*)SvANY(hv);
730     I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
731     register I32 newsize;
732     register I32 i;
733     register I32 j;
734     register HE **a;
735     register HE *entry;
736     register HE **oentry;
737
738     newsize = (I32) newmax;                     /* possible truncation here */
739     if (newsize != newmax || newmax <= oldsize)
740         return;
741     while ((newsize & (1 + ~newsize)) != newsize) {
742         newsize &= ~(newsize & (1 + ~newsize)); /* get proper power of 2 */
743     }
744     if (newsize < newmax)
745         newsize *= 2;
746     if (newsize < newmax)
747         return;                                 /* overflow detection */
748
749     a = (HE**)xhv->xhv_array;
750     if (a) {
751         nomemok = TRUE;
752 #ifdef STRANGE_MALLOC
753         Renew(a, newsize, HE*);
754 #else
755         i = newsize * sizeof(HE*);
756         j = MALLOC_OVERHEAD;
757         while (j - MALLOC_OVERHEAD < i)
758             j += j;
759         j -= MALLOC_OVERHEAD;
760         j /= sizeof(HE*);
761         assert(j >= newsize);
762         New(2, a, j, HE*);
763         Copy(xhv->xhv_array, a, oldsize, HE*);
764         if (oldsize >= 64) {
765             offer_nice_chunk(xhv->xhv_array,
766                              oldsize * sizeof(HE*) * 2 - MALLOC_OVERHEAD);
767         }
768         else
769             Safefree(xhv->xhv_array);
770 #endif
771         nomemok = FALSE;
772         Zero(&a[oldsize], newsize-oldsize, HE*); /* zero 2nd half*/
773     }
774     else {
775         Newz(0, a, newsize, HE*);
776     }
777     xhv->xhv_max = --newsize;
778     xhv->xhv_array = (char*)a;
779     if (!xhv->xhv_fill)                         /* skip rest if no entries */
780         return;
781
782     for (i=0; i<oldsize; i++,a++) {
783         if (!*a)                                /* non-existent */
784             continue;
785         for (oentry = a, entry = *a; entry; entry = *oentry) {
786             if ((j = (HeHASH(entry) & newsize)) != i) {
787                 j -= i;
788                 *oentry = HeNEXT(entry);
789                 if (!(HeNEXT(entry) = a[j]))
790                     xhv->xhv_fill++;
791                 a[j] = entry;
792                 continue;
793             }
794             else
795                 oentry = &HeNEXT(entry);
796         }
797         if (!*a)                                /* everything moved */
798             xhv->xhv_fill--;
799     }
800 }
801
802 HV *
803 newHV(void)
804 {
805     register HV *hv;
806     register XPVHV* xhv;
807
808     hv = (HV*)NEWSV(502,0);
809     sv_upgrade((SV *)hv, SVt_PVHV);
810     xhv = (XPVHV*)SvANY(hv);
811     SvPOK_off(hv);
812     SvNOK_off(hv);
813 #ifndef NODEFAULT_SHAREKEYS    
814     HvSHAREKEYS_on(hv);         /* key-sharing on by default */
815 #endif    
816     xhv->xhv_max = 7;           /* start with 8 buckets */
817     xhv->xhv_fill = 0;
818     xhv->xhv_pmroot = 0;
819     (void)hv_iterinit(hv);      /* so each() will start off right */
820     return hv;
821 }
822
823 void
824 hv_free_ent(HV *hv, register HE *entry)
825 {
826     if (!entry)
827         return;
828     if (isGV(HeVAL(entry)) && GvCVu(HeVAL(entry)) && HvNAME(hv))
829         sub_generation++;       /* may be deletion of method from stash */
830     SvREFCNT_dec(HeVAL(entry));
831     if (HeKLEN(entry) == HEf_SVKEY) {
832         SvREFCNT_dec(HeKEY_sv(entry));
833         Safefree(HeKEY_hek(entry));
834     }
835     else if (HvSHAREKEYS(hv))
836         unshare_hek(HeKEY_hek(entry));
837     else
838         Safefree(HeKEY_hek(entry));
839     del_he(entry);
840 }
841
842 void
843 hv_delayfree_ent(HV *hv, register HE *entry)
844 {
845     if (!entry)
846         return;
847     if (isGV(HeVAL(entry)) && GvCVu(HeVAL(entry)) && HvNAME(hv))
848         sub_generation++;       /* may be deletion of method from stash */
849     sv_2mortal(HeVAL(entry));   /* free between statements */
850     if (HeKLEN(entry) == HEf_SVKEY) {
851         sv_2mortal(HeKEY_sv(entry));
852         Safefree(HeKEY_hek(entry));
853     }
854     else if (HvSHAREKEYS(hv))
855         unshare_hek(HeKEY_hek(entry));
856     else
857         Safefree(HeKEY_hek(entry));
858     del_he(entry);
859 }
860
861 void
862 hv_clear(HV *hv)
863 {
864     register XPVHV* xhv;
865     if (!hv)
866         return;
867     xhv = (XPVHV*)SvANY(hv);
868     hfreeentries(hv);
869     xhv->xhv_fill = 0;
870     xhv->xhv_keys = 0;
871     if (xhv->xhv_array)
872         (void)memzero(xhv->xhv_array, (xhv->xhv_max + 1) * sizeof(HE*));
873
874     if (SvRMAGICAL(hv))
875         mg_clear((SV*)hv); 
876 }
877
878 STATIC void
879 hfreeentries(HV *hv)
880 {
881     register HE **array;
882     register HE *entry;
883     register HE *oentry = Null(HE*);
884     I32 riter;
885     I32 max;
886
887     if (!hv)
888         return;
889     if (!HvARRAY(hv))
890         return;
891
892     riter = 0;
893     max = HvMAX(hv);
894     array = HvARRAY(hv);
895     entry = array[0];
896     for (;;) {
897         if (entry) {
898             oentry = entry;
899             entry = HeNEXT(entry);
900             hv_free_ent(hv, oentry);
901         }
902         if (!entry) {
903             if (++riter > max)
904                 break;
905             entry = array[riter];
906         } 
907     }
908     (void)hv_iterinit(hv);
909 }
910
911 void
912 hv_undef(HV *hv)
913 {
914     register XPVHV* xhv;
915     if (!hv)
916         return;
917     xhv = (XPVHV*)SvANY(hv);
918     hfreeentries(hv);
919     Safefree(xhv->xhv_array);
920     if (HvNAME(hv)) {
921         Safefree(HvNAME(hv));
922         HvNAME(hv) = 0;
923     }
924     xhv->xhv_array = 0;
925     xhv->xhv_max = 7;           /* it's a normal hash */
926     xhv->xhv_fill = 0;
927     xhv->xhv_keys = 0;
928
929     if (SvRMAGICAL(hv))
930         mg_clear((SV*)hv); 
931 }
932
933 I32
934 hv_iterinit(HV *hv)
935 {
936     register XPVHV* xhv;
937     HE *entry;
938
939     if (!hv)
940         croak("Bad hash");
941     xhv = (XPVHV*)SvANY(hv);
942     entry = xhv->xhv_eiter;
943 #ifdef DYNAMIC_ENV_FETCH  /* set up %ENV for iteration */
944     if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
945         prime_env_iter();
946 #endif
947     if (entry && HvLAZYDEL(hv)) {       /* was deleted earlier? */
948         HvLAZYDEL_off(hv);
949         hv_free_ent(hv, entry);
950     }
951     xhv->xhv_riter = -1;
952     xhv->xhv_eiter = Null(HE*);
953     return xhv->xhv_fill;       /* should be xhv->xhv_keys? May change later */
954 }
955
956 HE *
957 hv_iternext(HV *hv)
958 {
959     register XPVHV* xhv;
960     register HE *entry;
961     HE *oldentry;
962     MAGIC* mg;
963
964     if (!hv)
965         croak("Bad hash");
966     xhv = (XPVHV*)SvANY(hv);
967     oldentry = entry = xhv->xhv_eiter;
968
969     if (SvRMAGICAL(hv) && (mg = mg_find((SV*)hv,'P'))) {
970         SV *key = sv_newmortal();
971         if (entry) {
972             sv_setsv(key, HeSVKEY_force(entry));
973             SvREFCNT_dec(HeSVKEY(entry));       /* get rid of previous key */
974         }
975         else {
976             char *k;
977             HEK *hek;
978
979             xhv->xhv_eiter = entry = new_he();  /* one HE per MAGICAL hash */
980             Zero(entry, 1, HE);
981             Newz(54, k, HEK_BASESIZE + sizeof(SV*), char);
982             hek = (HEK*)k;
983             HeKEY_hek(entry) = hek;
984             HeKLEN(entry) = HEf_SVKEY;
985         }
986         magic_nextpack((SV*) hv,mg,key);
987         if (SvOK(key)) {
988             /* force key to stay around until next time */
989             HeSVKEY_set(entry, SvREFCNT_inc(key));
990             return entry;               /* beware, hent_val is not set */
991         }
992         if (HeVAL(entry))
993             SvREFCNT_dec(HeVAL(entry));
994         Safefree(HeKEY_hek(entry));
995         del_he(entry);
996         xhv->xhv_eiter = Null(HE*);
997         return Null(HE*);
998     }
999
1000     if (!xhv->xhv_array)
1001         Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char);
1002     if (entry)
1003         entry = HeNEXT(entry);
1004     while (!entry) {
1005         ++xhv->xhv_riter;
1006         if (xhv->xhv_riter > xhv->xhv_max) {
1007             xhv->xhv_riter = -1;
1008             break;
1009         }
1010         entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter];
1011     }
1012
1013     if (oldentry && HvLAZYDEL(hv)) {            /* was deleted earlier? */
1014         HvLAZYDEL_off(hv);
1015         hv_free_ent(hv, oldentry);
1016     }
1017
1018     xhv->xhv_eiter = entry;
1019     return entry;
1020 }
1021
1022 char *
1023 hv_iterkey(register HE *entry, I32 *retlen)
1024 {
1025     if (HeKLEN(entry) == HEf_SVKEY) {
1026         STRLEN len;
1027         char *p = SvPV(HeKEY_sv(entry), len);
1028         *retlen = len;
1029         return p;
1030     }
1031     else {
1032         *retlen = HeKLEN(entry);
1033         return HeKEY(entry);
1034     }
1035 }
1036
1037 /* unlike hv_iterval(), this always returns a mortal copy of the key */
1038 SV *
1039 hv_iterkeysv(register HE *entry)
1040 {
1041     if (HeKLEN(entry) == HEf_SVKEY)
1042         return sv_mortalcopy(HeKEY_sv(entry));
1043     else
1044         return sv_2mortal(newSVpv((HeKLEN(entry) ? HeKEY(entry) : ""),
1045                                   HeKLEN(entry)));
1046 }
1047
1048 SV *
1049 hv_iterval(HV *hv, register HE *entry)
1050 {
1051     if (SvRMAGICAL(hv)) {
1052         if (mg_find((SV*)hv,'P')) {
1053             SV* sv = sv_newmortal();
1054             if (HeKLEN(entry) == HEf_SVKEY)
1055                 mg_copy((SV*)hv, sv, (char*)HeKEY_sv(entry), HEf_SVKEY);
1056             else mg_copy((SV*)hv, sv, HeKEY(entry), HeKLEN(entry));
1057             return sv;
1058         }
1059     }
1060     return HeVAL(entry);
1061 }
1062
1063 SV *
1064 hv_iternextsv(HV *hv, char **key, I32 *retlen)
1065 {
1066     HE *he;
1067     if ( (he = hv_iternext(hv)) == NULL)
1068         return NULL;
1069     *key = hv_iterkey(he, retlen);
1070     return hv_iterval(hv, he);
1071 }
1072
1073 void
1074 hv_magic(HV *hv, GV *gv, int how)
1075 {
1076     sv_magic((SV*)hv, (SV*)gv, how, Nullch, 0);
1077 }
1078
1079 char*   
1080 sharepvn(char *sv, I32 len, U32 hash)
1081 {
1082     return HEK_KEY(share_hek(sv, len, hash));
1083 }
1084
1085 /* possibly free a shared string if no one has access to it
1086  * len and hash must both be valid for str.
1087  */
1088 void
1089 unsharepvn(char *str, I32 len, U32 hash)
1090 {
1091     register XPVHV* xhv;
1092     register HE *entry;
1093     register HE **oentry;
1094     register I32 i = 1;
1095     I32 found = 0;
1096     
1097     /* what follows is the moral equivalent of:
1098     if ((Svp = hv_fetch(strtab, tmpsv, FALSE, hash))) {
1099         if (--*Svp == Nullsv)
1100             hv_delete(strtab, str, len, G_DISCARD, hash);
1101     } */
1102     xhv = (XPVHV*)SvANY(strtab);
1103     /* assert(xhv_array != 0) */
1104     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
1105     for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
1106         if (HeHASH(entry) != hash)              /* strings can't be equal */
1107             continue;
1108         if (HeKLEN(entry) != len)
1109             continue;
1110         if (memNE(HeKEY(entry),str,len))        /* is this it? */
1111             continue;
1112         found = 1;
1113         if (--HeVAL(entry) == Nullsv) {
1114             *oentry = HeNEXT(entry);
1115             if (i && !*oentry)
1116                 xhv->xhv_fill--;
1117             Safefree(HeKEY_hek(entry));
1118             del_he(entry);
1119             --xhv->xhv_keys;
1120         }
1121         break;
1122     }
1123     
1124     if (!found)
1125         warn("Attempt to free non-existent shared string");    
1126 }
1127
1128 /* get a (constant) string ptr from the global string table
1129  * string will get added if it is not already there.
1130  * len and hash must both be valid for str.
1131  */
1132 HEK *
1133 share_hek(char *str, I32 len, register U32 hash)
1134 {
1135     register XPVHV* xhv;
1136     register HE *entry;
1137     register HE **oentry;
1138     register I32 i = 1;
1139     I32 found = 0;
1140
1141     /* what follows is the moral equivalent of:
1142        
1143     if (!(Svp = hv_fetch(strtab, str, len, FALSE)))
1144         hv_store(strtab, str, len, Nullsv, hash);
1145     */
1146     xhv = (XPVHV*)SvANY(strtab);
1147     /* assert(xhv_array != 0) */
1148     oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
1149     for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
1150         if (HeHASH(entry) != hash)              /* strings can't be equal */
1151             continue;
1152         if (HeKLEN(entry) != len)
1153             continue;
1154         if (memNE(HeKEY(entry),str,len))        /* is this it? */
1155             continue;
1156         found = 1;
1157         break;
1158     }
1159     if (!found) {
1160         entry = new_he();
1161         HeKEY_hek(entry) = save_hek(str, len, hash);
1162         HeVAL(entry) = Nullsv;
1163         HeNEXT(entry) = *oentry;
1164         *oentry = entry;
1165         xhv->xhv_keys++;
1166         if (i) {                                /* initial entry? */
1167             ++xhv->xhv_fill;
1168             if (xhv->xhv_keys > xhv->xhv_max)
1169                 hsplit(strtab);
1170         }
1171     }
1172
1173     ++HeVAL(entry);                             /* use value slot as REFCNT */
1174     return HeKEY_hek(entry);
1175 }
1176
1177
1178