1 #define PERL_NO_GET_CONTEXT
7 MODULE = Hash::Util PACKAGE = Hash::Util
10 _clear_placeholders(hashref)
16 hv = MUTABLE_HV(hashref);
17 hv_clear_placeholders(hv);
20 all_keys(hash,keys,placeholder)
30 av_clear(placeholder);
32 (void)hv_iterinit(hash);
33 while((he = hv_iternext_flags(hash, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
35 av_push(HeVAL(he) == &PL_sv_placeholder ? placeholder : keys,
44 Hash::Util::legal_ref_keys = 1
49 (void)hv_iterinit(hash);
50 while((he = hv_iternext_flags(hash, HV_ITERNEXT_WANTPLACEHOLDERS))!= NULL) {
52 if (ix || HeVAL(he) == &PL_sv_placeholder) {
58 hv_store(hash, key, val)
66 if (!hv_store_ent(hash, key, val, 0)) {
78 mXPUSHs(newSVpvn((char *)PERL_HASH_SEED,PERL_HASH_SEED_BYTES));
83 hash_value(string,...)
90 char *pv= SvPV(string,len);
92 PERL_HASH(uv, pv, len);
95 U8 *seedbuf= (U8 *)SvPV(ST(1),seedlen);
96 if ( seedlen < PERL_HASH_SEED_BYTES ) {
98 Perl_croak(aTHX_ "seed len must be at least %d long only got %"UVuf" bytes", PERL_HASH_SEED_BYTES, (UV)seedlen);
101 PERL_HASH_WITH_SEED(seedbuf, uv, pv, len);
107 hash_traversal_mask(rhv, ...)
111 #ifdef PERL_HASH_RANDOMIZE_KEYS
112 if (SvROK(rhv) && SvTYPE(SvRV(rhv))==SVt_PVHV && !SvMAGICAL(SvRV(rhv))) {
113 HV *hv = (HV *)SvRV(rhv);
115 hv_rand_set(hv, SvUV(ST(1)));
118 XSRETURN_UV(HvRAND_get(hv));
124 Perl_croak(aTHX_ "Perl has not been compiled with support for randomized hash key traversal");
135 Takes a non-magical hash ref as an argument and returns a list of
136 statistics about the hash. The number and keys and the size of the
137 array will always be reported as the first two values. If the array is
138 actually allocated (they are lazily allocated), then additionally
139 will return a list of counts of bucket lengths. In other words in
141 ($keys, $buckets, $used, @length_count)= hash::bucket_info(\%hash);
143 $length_count[0] is the number of empty buckets, and $length_count[1]
144 is the number of buckets with only one key in it, $buckets - $length_count[0]
145 gives the number of used buckets, and @length_count-1 is the maximum
148 If the argument is not a hash ref, or if it is magical, then returns
149 nothing (the empty list).
152 const HV * hv = NULL;
153 if (SvROK(rhv) && SvTYPE(SvRV(rhv))==SVt_PVHV && !SvMAGICAL(SvRV(rhv))) {
154 hv = (const HV *) SvRV(rhv);
155 } else if (!SvOK(rhv)) {
159 U32 max_bucket_index= HvMAX(hv);
160 U32 total_keys= HvUSEDKEYS(hv);
161 HE **bucket_array= HvARRAY(hv);
163 mXPUSHi(max_bucket_index+1);
164 mXPUSHi(0); /* for the number of used buckets */
165 #define BUCKET_INFO_ITEMS_ON_STACK 3
167 XSRETURN(BUCKET_INFO_ITEMS_ON_STACK);
169 /* we use chain_length to index the stack - we eliminate an add
170 * by initializing things with the number of items already on the stack.
171 * If we have 2 items then ST(2+0) (the third stack item) will be the counter
172 * for empty chains, ST(2+1) will be for chains with one element, etc.
174 I32 max_chain_length= BUCKET_INFO_ITEMS_ON_STACK - 1; /* so we do not have to do an extra push for the 0 index */
177 for ( bucket_index= 0; bucket_index <= max_bucket_index; bucket_index++ ) {
178 I32 chain_length= BUCKET_INFO_ITEMS_ON_STACK;
179 for (he= bucket_array[bucket_index]; he; he= HeNEXT(he) ) {
182 while ( max_chain_length < chain_length ) {
186 SvIVX( ST( chain_length ) )++;
188 /* now set the number of used buckets */
189 SvIVX( ST( BUCKET_INFO_ITEMS_ON_STACK - 1 ) ) = max_bucket_index - SvIVX( ST( BUCKET_INFO_ITEMS_ON_STACK ) ) + 1;
190 XSRETURN( max_chain_length + 1 ); /* max_chain_length is the index of the last item on the stack, so we add 1 */
192 #undef BUCKET_INFO_ITEMS_ON_STACK
202 /* Returns an array of arrays representing key/bucket mappings.
203 * Each element of the array contains either an integer or a reference
204 * to an array of keys. A plain integer represents K empty buckets. An
205 * array ref represents a single bucket, with each element being a key in
206 * the hash. (Note this treats a placeholder as a normal key.)
208 * This allows one to "see" the keyorder. Note the "insert first" nature
209 * of the hash store, combined with regular remappings means that relative
210 * order of keys changes each remap.
212 const HV * hv = NULL;
213 if (SvROK(rhv) && SvTYPE(SvRV(rhv))==SVt_PVHV && !SvMAGICAL(SvRV(rhv))) {
214 hv = (const HV *) SvRV(rhv);
215 } else if (!SvOK(rhv)) {
219 HE **he_ptr= HvARRAY(hv);
228 Perl_croak(aTHX_ "hash::bucket_array only works on 'normal' hashes");
232 mXPUSHs(newRV_noinc((SV*)info_av));
233 for ( i= 0; i <= max; i++ ) {
235 for (he= he_ptr[i]; he; he= HeNEXT(he) ) {
243 av_push(info_av, newSViv(empty_count));
246 av_push(info_av, (SV *)newRV_noinc((SV *)key_av));
248 if (HeKLEN(he) == HEf_SVKEY) {
252 mode= SvUTF8(sv) ? 1 : 0;
256 mode= HeKUTF8(he) ? 1 : 0;
258 key_sv= newSVpvn(str,len);
259 av_push(key_av,key_sv);
268 av_push(info_av, newSViv(empty_count));
285 if ( SvTYPE(rhv)==SVt_PVHV ) {
286 #if PERL_VERSION < 25
287 SV *ret= Perl_hv_scalar(aTHX_ (HV*)rhv);
289 SV *ret= Perl_hv_bucket_ratio(aTHX_ (HV*)rhv);
306 if ( SvTYPE(rhv)==SVt_PVHV ) {
307 XSRETURN_UV(HvMAX((HV*)rhv)+1);
321 if ( SvTYPE(rhv)==SVt_PVHV ) {
322 XSRETURN_UV(HvFILL((HV*)rhv));