-/* $RCSfile: hash.h,v $$Revision: 4.1 $$Date: 92/08/07 18:21:52 $
+/* hv.h
*
- * Copyright (c) 1991, Larry Wall
+ * Copyright (c) 1991-1997, 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.
*
- * $Log: hash.h,v $
- * Revision 4.1 92/08/07 18:21:52 lwall
- *
- * Revision 4.0.1.2 91/11/05 17:24:31 lwall
- * patch11: random cleanup
- *
- * Revision 4.0.1.1 91/06/07 11:10:33 lwall
- * patch4: new copyright notice
- *
- * Revision 4.0 91/03/20 01:22:38 lwall
- * 4.0 baseline.
- *
*/
-#define FILLPCT 80 /* don't make greater than 99 */
-#define DBM_CACHE_MAX 63 /* cache 64 entries for dbm file */
- /* (resident array acts as a write-thru cache)*/
-
-#define COEFFSIZE (16 * 8) /* size of coeff array */
-
typedef struct he HE;
+typedef struct hek HEK;
struct he {
HE *hent_next;
- char *hent_key;
+ HEK *hent_hek;
SV *hent_val;
- I32 hent_hash;
- I32 hent_klen;
};
+struct hek {
+ U32 hek_hash;
+ I32 hek_len;
+ char hek_key[1];
+};
+
+/* This structure must match the beginning of struct xpvmg in sv.h. */
struct xpvhv {
- char * xpv_pv; /* pointer to malloced string */
- STRLEN xpv_cur; /* length of xp_pv as a C string */
- STRLEN xpv_len; /* allocated size */
- STRLEN xof_off; /* ptr is incremented by offset */
+ char * xhv_array; /* pointer to malloced string */
+ STRLEN xhv_fill; /* how full xhv_array currently is */
+ STRLEN xhv_max; /* subscript of last element of xhv_array */
+ IV xhv_keys; /* how many elements in the array */
double xnv_nv; /* numeric value, if any */
MAGIC* xmg_magic; /* magic for scalar array */
HV* xmg_stash; /* class package */
- MAGIC* xhv_magic; /* magic for elements */
-
- HE **xhv_array;
- I32 xhv_max; /* subscript of last element of xhv_array */
- I32 xhv_dosplit; /* how full to get before splitting */
- I32 xhv_fill; /* how full xhv_array currently is */
I32 xhv_riter; /* current root of iterator */
HE *xhv_eiter; /* current entry of iterator */
PMOP *xhv_pmroot; /* list of pm's for this package */
char *xhv_name; /* name, if a symbol table */
-#ifdef SOME_DBM
-#ifdef HAS_GDBM
- GDBM_FILE xhv_dbm;
-#else
-#ifdef HAS_NDBM
- DBM *xhv_dbm;
-#else
- I32 xhv_dbm;
-#endif
-#endif
-#endif
- unsigned char xhv_coeffsize; /* is 0 for symbol tables */
};
+#define PERL_HASH(hash,str,len) \
+ STMT_START { \
+ register 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); \
+ } STMT_END
+
+
+/* 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 Nullhv Null(HV*)
-#define HvMAGIC(hv) ((XPVHV*) SvANY(hv))->xhv_magic
-#define HvARRAY(hv) ((XPVHV*) SvANY(hv))->xhv_array
-#define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max
-#define HvDOSPLIT(hv) ((XPVHV*) SvANY(hv))->xhv_dosplit
+#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
#define HvRITER(hv) ((XPVHV*) SvANY(hv))->xhv_riter
#define HvEITER(hv) ((XPVHV*) SvANY(hv))->xhv_eiter
#define HvPMROOT(hv) ((XPVHV*) SvANY(hv))->xhv_pmroot
#define HvNAME(hv) ((XPVHV*) SvANY(hv))->xhv_name
-#define HvDBM(hv) ((XPVHV*) SvANY(hv))->xhv_dbm
-#define HvCOEFFSIZE(hv) ((XPVHV*) SvANY(hv))->xhv_coeffsize
+
+#define HvSHAREKEYS(hv) (SvFLAGS(hv) & SVphv_SHAREKEYS)
+#define HvSHAREKEYS_on(hv) (SvFLAGS(hv) |= SVphv_SHAREKEYS)
+#define HvSHAREKEYS_off(hv) (SvFLAGS(hv) &= ~SVphv_SHAREKEYS)
+
+#define HvLAZYDEL(hv) (SvFLAGS(hv) & SVphv_LAZYDEL)
+#define HvLAZYDEL_on(hv) (SvFLAGS(hv) |= SVphv_LAZYDEL)
+#define HvLAZYDEL_off(hv) (SvFLAGS(hv) &= ~SVphv_LAZYDEL)
+
+#ifdef OVERLOAD
+
+/* Maybe amagical: */
+/* #define HV_AMAGICmb(hv) (SvFLAGS(hv) & (SVpgv_badAM | SVpgv_AM)) */
+
+#define HV_AMAGIC(hv) (SvFLAGS(hv) & SVpgv_AM)
+#define HV_AMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_AM)
+#define HV_AMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_AM)
+
+/*
+#define HV_AMAGICbad(hv) (SvFLAGS(hv) & SVpgv_badAM)
+#define HV_badAMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_badAM)
+#define HV_badAMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_badAM)
+*/
+
+#endif /* OVERLOAD */
+
+#define Nullhe Null(HE*)
+#define HeNEXT(he) (he)->hent_next
+#define HeKEY_hek(he) (he)->hent_hek
+#define HeKEY(he) HEK_KEY(HeKEY_hek(he))
+#define HeKEY_sv(he) (*(SV**)HeKEY(he))
+#define HeKLEN(he) HEK_LEN(HeKEY_hek(he))
+#define HeVAL(he) (he)->hent_val
+#define HeHASH(he) HEK_HASH(HeKEY_hek(he))
+#define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \
+ SvPV(HeKEY_sv(he),lp) : \
+ (((lp = HeKLEN(he)) >= 0) ? \
+ HeKEY(he) : Nullch))
+
+#define HeSVKEY(he) ((HeKEY(he) && \
+ HeKLEN(he) == HEf_SVKEY) ? \
+ HeKEY_sv(he) : Nullsv)
+
+#define HeSVKEY_force(he) (HeKEY(he) ? \
+ ((HeKLEN(he) == HEf_SVKEY) ? \
+ HeKEY_sv(he) : \
+ sv_2mortal(newSVpv(HeKEY(he), \
+ HeKLEN(he)))) : \
+ &PL_sv_undef)
+#define HeSVKEY_set(he,sv) ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv))
+
+#define Nullhek Null(HEK*)
+#define HEK_BASESIZE STRUCT_OFFSET(HEK, hek_key[0])
+#define HEK_HASH(hek) (hek)->hek_hash
+#define HEK_LEN(hek) (hek)->hek_len
+#define HEK_KEY(hek) (hek)->hek_key