[win32] merge changes#1014,1038 from maintbranch
[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{
16bdeea2 839 SV *val;
840
68dc0745 841 if (!entry)
79072805 842 return;
16bdeea2 843 val = HeVAL(entry);
257c9e5b 844 if (val && isGV(val) && GvCVu(val) && HvNAME(hv))
44a8e56a 845 sub_generation++; /* may be deletion of method from stash */
16bdeea2 846 SvREFCNT_dec(val);
68dc0745 847 if (HeKLEN(entry) == HEf_SVKEY) {
848 SvREFCNT_dec(HeKEY_sv(entry));
849 Safefree(HeKEY_hek(entry));
44a8e56a 850 }
851 else if (HvSHAREKEYS(hv))
68dc0745 852 unshare_hek(HeKEY_hek(entry));
fde52b5c 853 else
68dc0745 854 Safefree(HeKEY_hek(entry));
855 del_he(entry);
79072805 856}
857
858void
8ac85365 859hv_delayfree_ent(HV *hv, register HE *entry)
79072805 860{
68dc0745 861 if (!entry)
79072805 862 return;
68dc0745 863 if (isGV(HeVAL(entry)) && GvCVu(HeVAL(entry)) && HvNAME(hv))
44a8e56a 864 sub_generation++; /* may be deletion of method from stash */
68dc0745 865 sv_2mortal(HeVAL(entry)); /* free between statements */
866 if (HeKLEN(entry) == HEf_SVKEY) {
867 sv_2mortal(HeKEY_sv(entry));
868 Safefree(HeKEY_hek(entry));
44a8e56a 869 }
870 else if (HvSHAREKEYS(hv))
68dc0745 871 unshare_hek(HeKEY_hek(entry));
fde52b5c 872 else
68dc0745 873 Safefree(HeKEY_hek(entry));
874 del_he(entry);
79072805 875}
876
877void
8ac85365 878hv_clear(HV *hv)
79072805 879{
880 register XPVHV* xhv;
881 if (!hv)
882 return;
883 xhv = (XPVHV*)SvANY(hv);
463ee0b2 884 hfreeentries(hv);
79072805 885 xhv->xhv_fill = 0;
a0d0e21e 886 xhv->xhv_keys = 0;
79072805 887 if (xhv->xhv_array)
463ee0b2 888 (void)memzero(xhv->xhv_array, (xhv->xhv_max + 1) * sizeof(HE*));
a0d0e21e 889
890 if (SvRMAGICAL(hv))
891 mg_clear((SV*)hv);
79072805 892}
893
894static void
8ac85365 895hfreeentries(HV *hv)
79072805 896{
a0d0e21e 897 register HE **array;
68dc0745 898 register HE *entry;
899 register HE *oentry = Null(HE*);
a0d0e21e 900 I32 riter;
901 I32 max;
79072805 902
903 if (!hv)
904 return;
a0d0e21e 905 if (!HvARRAY(hv))
79072805 906 return;
a0d0e21e 907
908 riter = 0;
909 max = HvMAX(hv);
910 array = HvARRAY(hv);
68dc0745 911 entry = array[0];
a0d0e21e 912 for (;;) {
68dc0745 913 if (entry) {
914 oentry = entry;
915 entry = HeNEXT(entry);
916 hv_free_ent(hv, oentry);
a0d0e21e 917 }
68dc0745 918 if (!entry) {
a0d0e21e 919 if (++riter > max)
920 break;
68dc0745 921 entry = array[riter];
a0d0e21e 922 }
79072805 923 }
a0d0e21e 924 (void)hv_iterinit(hv);
79072805 925}
926
927void
8ac85365 928hv_undef(HV *hv)
79072805 929{
930 register XPVHV* xhv;
931 if (!hv)
932 return;
933 xhv = (XPVHV*)SvANY(hv);
463ee0b2 934 hfreeentries(hv);
79072805 935 Safefree(xhv->xhv_array);
85e6fe83 936 if (HvNAME(hv)) {
937 Safefree(HvNAME(hv));
938 HvNAME(hv) = 0;
939 }
79072805 940 xhv->xhv_array = 0;
aa689395 941 xhv->xhv_max = 7; /* it's a normal hash */
79072805 942 xhv->xhv_fill = 0;
a0d0e21e 943 xhv->xhv_keys = 0;
944
945 if (SvRMAGICAL(hv))
946 mg_clear((SV*)hv);
79072805 947}
948
79072805 949I32
8ac85365 950hv_iterinit(HV *hv)
79072805 951{
aa689395 952 register XPVHV* xhv;
953 HE *entry;
954
955 if (!hv)
956 croak("Bad hash");
957 xhv = (XPVHV*)SvANY(hv);
958 entry = xhv->xhv_eiter;
effa1e2d 959#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */
aa689395 960 if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
961 prime_env_iter();
effa1e2d 962#endif
72940dca 963 if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */
964 HvLAZYDEL_off(hv);
68dc0745 965 hv_free_ent(hv, entry);
72940dca 966 }
79072805 967 xhv->xhv_riter = -1;
968 xhv->xhv_eiter = Null(HE*);
c6601927 969 return xhv->xhv_keys; /* used to be xhv->xhv_fill before 5.004_65 */
79072805 970}
971
972HE *
8ac85365 973hv_iternext(HV *hv)
79072805 974{
975 register XPVHV* xhv;
976 register HE *entry;
a0d0e21e 977 HE *oldentry;
463ee0b2 978 MAGIC* mg;
79072805 979
980 if (!hv)
aa689395 981 croak("Bad hash");
79072805 982 xhv = (XPVHV*)SvANY(hv);
a0d0e21e 983 oldentry = entry = xhv->xhv_eiter;
463ee0b2 984
8990e307 985 if (SvRMAGICAL(hv) && (mg = mg_find((SV*)hv,'P'))) {
986 SV *key = sv_newmortal();
cd1469e6 987 if (entry) {
fde52b5c 988 sv_setsv(key, HeSVKEY_force(entry));
cd1469e6 989 SvREFCNT_dec(HeSVKEY(entry)); /* get rid of previous key */
990 }
a0d0e21e 991 else {
ff68c719 992 char *k;
bbce6d69 993 HEK *hek;
ff68c719 994
995 xhv->xhv_eiter = entry = new_he(); /* one HE per MAGICAL hash */
4633a7c4 996 Zero(entry, 1, HE);
ff68c719 997 Newz(54, k, HEK_BASESIZE + sizeof(SV*), char);
998 hek = (HEK*)k;
999 HeKEY_hek(entry) = hek;
fde52b5c 1000 HeKLEN(entry) = HEf_SVKEY;
a0d0e21e 1001 }
1002 magic_nextpack((SV*) hv,mg,key);
463ee0b2 1003 if (SvOK(key)) {
cd1469e6 1004 /* force key to stay around until next time */
bbce6d69 1005 HeSVKEY_set(entry, SvREFCNT_inc(key));
1006 return entry; /* beware, hent_val is not set */
463ee0b2 1007 }
fde52b5c 1008 if (HeVAL(entry))
1009 SvREFCNT_dec(HeVAL(entry));
ff68c719 1010 Safefree(HeKEY_hek(entry));
4633a7c4 1011 del_he(entry);
463ee0b2 1012 xhv->xhv_eiter = Null(HE*);
1013 return Null(HE*);
79072805 1014 }
463ee0b2 1015
79072805 1016 if (!xhv->xhv_array)
4633a7c4 1017 Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char);
fde52b5c 1018 if (entry)
1019 entry = HeNEXT(entry);
1020 while (!entry) {
1021 ++xhv->xhv_riter;
1022 if (xhv->xhv_riter > xhv->xhv_max) {
1023 xhv->xhv_riter = -1;
1024 break;
79072805 1025 }
fde52b5c 1026 entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter];
1027 }
79072805 1028
72940dca 1029 if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */
1030 HvLAZYDEL_off(hv);
68dc0745 1031 hv_free_ent(hv, oldentry);
72940dca 1032 }
a0d0e21e 1033
79072805 1034 xhv->xhv_eiter = entry;
1035 return entry;
1036}
1037
1038char *
8ac85365 1039hv_iterkey(register HE *entry, I32 *retlen)
79072805 1040{
fde52b5c 1041 if (HeKLEN(entry) == HEf_SVKEY) {
fb73857a 1042 STRLEN len;
1043 char *p = SvPV(HeKEY_sv(entry), len);
1044 *retlen = len;
1045 return p;
fde52b5c 1046 }
1047 else {
1048 *retlen = HeKLEN(entry);
1049 return HeKEY(entry);
1050 }
1051}
1052
1053/* unlike hv_iterval(), this always returns a mortal copy of the key */
1054SV *
8ac85365 1055hv_iterkeysv(register HE *entry)
fde52b5c 1056{
1057 if (HeKLEN(entry) == HEf_SVKEY)
bbce6d69 1058 return sv_mortalcopy(HeKEY_sv(entry));
fde52b5c 1059 else
1060 return sv_2mortal(newSVpv((HeKLEN(entry) ? HeKEY(entry) : ""),
1061 HeKLEN(entry)));
79072805 1062}
1063
1064SV *
8ac85365 1065hv_iterval(HV *hv, register HE *entry)
79072805 1066{
8990e307 1067 if (SvRMAGICAL(hv)) {
463ee0b2 1068 if (mg_find((SV*)hv,'P')) {
8990e307 1069 SV* sv = sv_newmortal();
bbce6d69 1070 if (HeKLEN(entry) == HEf_SVKEY)
1071 mg_copy((SV*)hv, sv, (char*)HeKEY_sv(entry), HEf_SVKEY);
1072 else mg_copy((SV*)hv, sv, HeKEY(entry), HeKLEN(entry));
463ee0b2 1073 return sv;
1074 }
79072805 1075 }
fde52b5c 1076 return HeVAL(entry);
79072805 1077}
1078
a0d0e21e 1079SV *
8ac85365 1080hv_iternextsv(HV *hv, char **key, I32 *retlen)
a0d0e21e 1081{
1082 HE *he;
1083 if ( (he = hv_iternext(hv)) == NULL)
1084 return NULL;
1085 *key = hv_iterkey(he, retlen);
1086 return hv_iterval(hv, he);
1087}
1088
79072805 1089void
8ac85365 1090hv_magic(HV *hv, GV *gv, int how)
79072805 1091{
a0d0e21e 1092 sv_magic((SV*)hv, (SV*)gv, how, Nullch, 0);
79072805 1093}
fde52b5c 1094
bbce6d69 1095char*
8ac85365 1096sharepvn(char *sv, I32 len, U32 hash)
bbce6d69 1097{
ff68c719 1098 return HEK_KEY(share_hek(sv, len, hash));
bbce6d69 1099}
1100
1101/* possibly free a shared string if no one has access to it
fde52b5c 1102 * len and hash must both be valid for str.
1103 */
bbce6d69 1104void
8ac85365 1105unsharepvn(char *str, I32 len, U32 hash)
fde52b5c 1106{
1107 register XPVHV* xhv;
1108 register HE *entry;
1109 register HE **oentry;
1110 register I32 i = 1;
1111 I32 found = 0;
bbce6d69 1112
fde52b5c 1113 /* what follows is the moral equivalent of:
bbce6d69 1114 if ((Svp = hv_fetch(strtab, tmpsv, FALSE, hash))) {
1115 if (--*Svp == Nullsv)
1116 hv_delete(strtab, str, len, G_DISCARD, hash);
1117 } */
fde52b5c 1118 xhv = (XPVHV*)SvANY(strtab);
1119 /* assert(xhv_array != 0) */
1120 oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
bbce6d69 1121 for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
fde52b5c 1122 if (HeHASH(entry) != hash) /* strings can't be equal */
1123 continue;
1124 if (HeKLEN(entry) != len)
1125 continue;
36477c24 1126 if (memNE(HeKEY(entry),str,len)) /* is this it? */
fde52b5c 1127 continue;
1128 found = 1;
bbce6d69 1129 if (--HeVAL(entry) == Nullsv) {
1130 *oentry = HeNEXT(entry);
1131 if (i && !*oentry)
1132 xhv->xhv_fill--;
ff68c719 1133 Safefree(HeKEY_hek(entry));
bbce6d69 1134 del_he(entry);
1135 --xhv->xhv_keys;
fde52b5c 1136 }
bbce6d69 1137 break;
fde52b5c 1138 }
bbce6d69 1139
1140 if (!found)
1141 warn("Attempt to free non-existent shared string");
fde52b5c 1142}
1143
bbce6d69 1144/* get a (constant) string ptr from the global string table
1145 * string will get added if it is not already there.
fde52b5c 1146 * len and hash must both be valid for str.
1147 */
bbce6d69 1148HEK *
8ac85365 1149share_hek(char *str, I32 len, register U32 hash)
fde52b5c 1150{
1151 register XPVHV* xhv;
1152 register HE *entry;
1153 register HE **oentry;
1154 register I32 i = 1;
1155 I32 found = 0;
bbce6d69 1156
fde52b5c 1157 /* what follows is the moral equivalent of:
bbce6d69 1158
1159 if (!(Svp = hv_fetch(strtab, str, len, FALSE)))
1160 hv_store(strtab, str, len, Nullsv, hash);
1161 */
fde52b5c 1162 xhv = (XPVHV*)SvANY(strtab);
1163 /* assert(xhv_array != 0) */
1164 oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
bbce6d69 1165 for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
fde52b5c 1166 if (HeHASH(entry) != hash) /* strings can't be equal */
1167 continue;
1168 if (HeKLEN(entry) != len)
1169 continue;
36477c24 1170 if (memNE(HeKEY(entry),str,len)) /* is this it? */
fde52b5c 1171 continue;
1172 found = 1;
fde52b5c 1173 break;
1174 }
bbce6d69 1175 if (!found) {
1176 entry = new_he();
ff68c719 1177 HeKEY_hek(entry) = save_hek(str, len, hash);
bbce6d69 1178 HeVAL(entry) = Nullsv;
1179 HeNEXT(entry) = *oentry;
1180 *oentry = entry;
1181 xhv->xhv_keys++;
1182 if (i) { /* initial entry? */
1183 ++xhv->xhv_fill;
1184 if (xhv->xhv_keys > xhv->xhv_max)
1185 hsplit(strtab);
1186 }
1187 }
1188
1189 ++HeVAL(entry); /* use value slot as REFCNT */
ff68c719 1190 return HeKEY_hek(entry);
fde52b5c 1191}
1192
bbce6d69 1193
61c8b479 1194