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