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