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