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