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