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