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