X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=9d6be7fce9bec3ad78d5362bf340b804df5f4679;hb=0a7c7f4fca760548390159c148b40caeb4e5a91d;hp=5bc38a0a79ae8c02c81136cc611276c8e68f16fc;hpb=3818b22bb9ef820a2553aa5e3504220f3b156f21;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index 5bc38a0..9d6be7f 100644 --- a/hv.h +++ b/hv.h @@ -1,27 +1,31 @@ /* hv.h * - * Copyright (c) 1991-2000, Larry Wall + * Copyright (c) 1991-2001, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ +/* typedefs to eliminate some typing */ typedef struct he HE; typedef struct hek HEK; +/* entry in hash value chain */ struct he { - HE *hent_next; - HEK *hent_hek; - SV *hent_val; + HE *hent_next; /* next entry in chain */ + HEK *hent_hek; /* hash key */ + SV *hent_val; /* scalar value that was hashed */ }; +/* hash key -- defined separately for use as shared pointer */ struct hek { - U32 hek_hash; - I32 hek_len; - char hek_key[1]; + U32 hek_hash; /* hash of key */ + I32 hek_len; /* length of hash key */ + char hek_key[1]; /* variable-length hash key */ }; +/* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { char * xhv_array; /* pointer to malloced string */ @@ -38,20 +42,29 @@ struct xpvhv { char *xhv_name; /* name, if a symbol table */ }; +/* hash a key */ +/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins */ +/* from requirements by Colin Plumb. */ +/* (http://burtleburtle.net/bob/hash/doobs.html) */ #define PERL_HASH(hash,str,len) \ STMT_START { \ register const char *s_PeRlHaSh = str; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = 0; \ - while (i_PeRlHaSh--) \ - hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ - (hash) = hash_PeRlHaSh + (hash_PeRlHaSh>>5); \ + while (i_PeRlHaSh--) { \ + hash_PeRlHaSh += *s_PeRlHaSh++; \ + hash_PeRlHaSh += (hash_PeRlHaSh << 10); \ + hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6); \ + } \ + hash_PeRlHaSh += (hash_PeRlHaSh << 3); \ + hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \ + (hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15)); \ } STMT_END /* =for apidoc AmU||HEf_SVKEY This flag, used in the length slot of hash entries and magic structures, -specifies the structure contains a C pointer where a C pointer +specifies the structure contains an C pointer where a C pointer is to be expected. (For information only--not to be used). =for apidoc AmU||Nullhv @@ -106,11 +119,11 @@ C. */ /* these hash entry flags ride on hent_klen (for use only in magic/tied HVs) */ -#define HEf_SVKEY -2 /* hent_key is a SV* */ +#define HEf_SVKEY -2 /* hent_key is an SV* */ #define Nullhv Null(HV*) -#define HvARRAY(hv) ((HE**)((XPVHV*) SvANY(hv))->xhv_array) +#define HvARRAY(hv) (*(HE***)&((XPVHV*) SvANY(hv))->xhv_array) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill #define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max #define HvKEYS(hv) ((XPVHV*) SvANY(hv))->xhv_keys @@ -146,6 +159,8 @@ C. #define HeKEY(he) HEK_KEY(HeKEY_hek(he)) #define HeKEY_sv(he) (*(SV**)HeKEY(he)) #define HeKLEN(he) HEK_LEN(HeKEY_hek(he)) +#define HeKUTF8(he) HEK_UTF8(HeKEY_hek(he)) +#define HeKLEN_UTF8(he) (HeKUTF8(he) ? -HeKLEN(he) : HeKLEN(he)) #define HeVAL(he) (he)->hent_val #define HeHASH(he) HEK_HASH(HeKEY_hek(he)) #define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \ @@ -170,7 +185,9 @@ C. #define HEK_HASH(hek) (hek)->hek_hash #define HEK_LEN(hek) (hek)->hek_len #define HEK_KEY(hek) (hek)->hek_key +#define HEK_UTF8(hek) (*(HEK_KEY(hek)+HEK_LEN(hek))) +/* calculate HV array allocation */ #if defined(STRANGE_MALLOC) || defined(MYMALLOC) # define PERL_HV_ARRAY_ALLOC_BYTES(size) ((size) * sizeof(HE*)) #else