summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@engin.umich.edu>1997-02-25 13:24:02 -0500
committerChip Salzenberg <chip@atlantic.net>1997-02-25 13:12:02 +1200
commita61fe43df197fcc70e6f310c06ee17d52b606c45 (patch)
tree6b7e3f52449e9376b87b4806f41d1a92a07831c0
parent20efc0829f6564c44574762adb07e8865bc14026 (diff)
downloadperl-a61fe43df197fcc70e6f310c06ee17d52b606c45.tar.gz
Clean up and document API for hashes
On Tue, 25 Feb 1997 09:01:57 EST, Chip Salzenberg wrote: >I've had 99.44% good reports about _90. I'd love to go public >immediately, but Sarathy's perl_call fix is just too valuable to pass >up, and there's a taint test in the works. So please don't tell >anyone that _90 is the first public beta; that will likely be _91. FWIW, the Beta Zvoid is alive and kicking on Linux 2.0.28. You might want to put this in too. (The patches to hv.h are mostly to an unused macro that will be useful for extension writers). p5p-msgid: <199702251824.NAA14859@aatma.engin.umich.edu>
-rw-r--r--hv.c1
-rw-r--r--hv.h10
-rw-r--r--perl.c4
-rw-r--r--pod/perldelta.pod12
-rw-r--r--pod/perlguts.pod160
-rw-r--r--pp_ctl.c5
6 files changed, 179 insertions, 13 deletions
diff --git a/hv.c b/hv.c
index 1ae7ad952d..ab6eac734a 100644
--- a/hv.c
+++ b/hv.c
@@ -177,7 +177,6 @@ register U32 hash;
char *k;
New(54, k, HEK_BASESIZE + sizeof(SV*), char);
HeKEY_hek(&mh) = (HEK*)k;
- HeKLEN(&mh) = HEf_SVKEY; /* key will always hold an SV* */
}
HeSVKEY_set(&mh, keysv);
HeVAL(&mh) = sv;
diff --git a/hv.h b/hv.h
index 7c04cc2428..7c80ca3d0d 100644
--- a/hv.h
+++ b/hv.h
@@ -95,9 +95,11 @@ struct xpvhv {
#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) ((HeKLEN(he) == HEf_SVKEY) ? \
- SvPV(HeKEY_sv(he),na) : \
- HeKEY(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)
@@ -108,7 +110,7 @@ struct xpvhv {
sv_2mortal(newSVpv(HeKEY(he), \
HeKLEN(he)))) : \
&sv_undef)
-#define HeSVKEY_set(he,sv) (HeKEY_sv(he) = sv)
+#define HeSVKEY_set(he,sv) ((HeKEY_sv(he) = sv), (HeKLEN(he) = HEf_SVKEY))
#define Nullhek Null(HEK*)
#define HEK_BASESIZE STRUCT_OFFSET(HEK, hek_key[0])
diff --git a/perl.c b/perl.c
index 8794dd69fe..9f3942e68f 100644
--- a/perl.c
+++ b/perl.c
@@ -509,7 +509,6 @@ setuid perl scripts securely.\n");
calllist(endav);
return STATUS_NATIVE_EXPORT;
case 3:
- mustcatch = FALSE;
PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
return 1;
}
@@ -801,7 +800,6 @@ PerlInterpreter *sv_interp;
#endif
return STATUS_NATIVE_EXPORT;
case 3:
- mustcatch = FALSE;
if (!restartop) {
PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
FREETMPS;
@@ -1032,7 +1030,6 @@ I32 flags; /* See G_* flags in cop.h */
my_exit_jump();
/* NOTREACHED */
case 3:
- mustcatch = FALSE;
if (restartop) {
op = restartop;
restartop = 0;
@@ -1143,7 +1140,6 @@ restart:
my_exit_jump();
/* NOTREACHED */
case 3:
- mustcatch = FALSE;
if (restartop) {
op = restartop;
restartop = 0;
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 23f216fce6..d202e70e56 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -671,6 +671,18 @@ C<perl_call_sv> is Perl's producing an "Undefined subroutine called"
error on the I<second> call to a given method (since there is no cache
on the first call).
+=item Extended API for manipulating hashes
+
+Internal handling of hash keys has changed. The old hashtable API
+is still fully supported, and will likely remain that way. The additions
+to the API allow passing keys as C<SV*>s, so that C<tied> hashes can be
+given real scalars as keys rather than plain strings (non-tied hashes still
+can only use strings as keys). All new extensions must use the new
+hash access functions and macros if they wish to use C<SV*> keys. These
+additions also make it feasible to manipulate whole C<HE*>s (hash entries),
+allowing for more efficient handling of hash data. See L<perlguts> for
+details.
+
=back
=head1 Documentation Changes
diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 77acc98aae..5766cc0589 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -322,6 +322,48 @@ The hash algorithm is defined in the C<PERL_HASH(hash, key, klen)> macro:
while (i--)
hash = hash * 33 + *s++;
+=head2 Hash API Extensions
+
+Beginning with version 5.004, the following functions are also supported:
+
+ HE* hv_fetch_ent (HV* tb, SV* key, I32 lval, U32 hash);
+ HE* hv_store_ent (HV* tb, SV* key, SV* val, U32 hash);
+
+ bool hv_exists_ent (HV* tb, SV* key, U32 hash);
+ SV* hv_delete_ent (HV* tb, SV* key, I32 flags, U32 hash);
+
+ SV* hv_iterkeysv (HE* entry);
+
+Note that these functions take C<SV*> keys, which simplifies writing
+of extension code that deals with hash structures. These functions
+also allow passing of C<SV*> keys to C<tie> functions without forcing
+you to stringify the keys (unlike the previous set of functions).
+
+They also return and accept whole hash entries (C<HE*>), making their
+use more efficient (since the hash number for a particular string
+doesn't have to be recomputed every time). See L<API LISTING> later in
+this document for detailed descriptions.
+
+The following macros must always be used to access the contents of hash
+entries. Note that the arguments to these macros must be simple
+variables, since they may get evaluated more than once. See
+L<API LISTING> later in this document for detailed descriptions of these
+macros.
+
+ HePV(HE* he, STRLEN len)
+ HeVAL(HE* he)
+ HeHASH(HE* he)
+ HeSVKEY(HE* he)
+ HeSVKEY_force(HE* he)
+ HeSVKEY_set(HE* he, SV* sv)
+
+These two lower level macros are defined, but must only be used when
+dealing with keys that are not C<SV*>s:
+
+ HeKEY(HE* he)
+ HeKLEN(HE* he)
+
+
=head2 References
References are a special type of scalar that point to other data types
@@ -1392,6 +1434,12 @@ statement (or thereabouts) with C<sv_2mortal>. See C<hv_iternext>.
void he_delayfree _((HV* hv, HE* hent));
+=item HEf_SVKEY
+
+This flag, used in the length slot of hash entries and magic
+structures, specifies the structure contains a C<SV*> pointer where a
+C<char*> pointer is to be expected. (For information only--not to be used).
+
=item he_free
Releases a hash entry, such as while iterating though the hash. See
@@ -1399,6 +1447,71 @@ C<hv_iternext>.
void he_free _((HV* hv, HE* hent));
+=item HeHASH
+
+Returns the computed hash (type C<U32>) stored in the hash entry.
+
+ HeHASH(HE* he)
+
+=item HeKEY
+
+Returns the actual pointer stored in the key slot of the hash entry.
+The pointer may be either C<char*> or C<SV*>, depending on the value of
+C<HeKLEN()>. Can be assigned to. The C<HePV()> or C<HeSVKEY()> macros
+are usually preferable for finding the value of a key.
+
+ HeKEY(HE* he)
+
+=item HeKLEN
+
+If this is negative, and amounts to C<HEf_SVKEY>, it indicates the entry
+holds an C<SV*> key. Otherwise, holds the actual length of the key.
+Can be assigned to. The C<HePV()> macro is usually preferable for finding
+key lengths.
+
+ HeKLEN(HE* he)
+
+=item HePV
+
+Returns the key slot of the hash entry as a C<char*> value, doing any
+necessary dereferencing of possibly C<SV*> keys. The length of
+the string is placed in C<len> (this is a macro, so do I<not> use
+C<&len>). If you do not care about what the length of the key is,
+you may use the global variable C<na>. Remember though, that hash
+keys in perl are free to contain embedded nulls, so using C<strlen()>
+or similar is not a good way to find the length of hash keys.
+This is very similar to the C<SvPV()> macro described elsewhere in
+this document.
+
+ HePV(HE* he, STRLEN len)
+
+=item HeSVKEY
+
+Returns the key as an C<SV*>, or C<Nullsv> if the hash entry
+does not contain an C<SV*> key.
+
+ HeSVKEY(HE* he)
+
+=item HeSVKEY_force
+
+Returns the key as an C<SV*>. Will create and return a temporary
+mortal C<SV*> if the hash entry contains only a C<char*> key.
+
+ HeSVKEY_force(HE* he)
+
+=item HeSVKEY_set
+
+Sets the key to a given C<SV*>, taking care to set the appropriate flags
+to indicate the presence of an C<SV*> key.
+
+ HeSVKEY_set(HE* he, SV* sv)
+
+=item HeVAL
+
+Returns the value slot (type C<SV*>) stored in the hash entry.
+
+ HeVAL(HE* he)
+
=item hv_clear
Clears a hash, making it empty.
@@ -1414,6 +1527,15 @@ returned.
SV* hv_delete _((HV* tb, char* key, U32 klen, I32 flags));
+=item hv_delete_ent
+
+Deletes a key/value pair in the hash. The value SV is removed from the hash
+and returned to the caller. The C<flags> value will normally be zero; if set
+to G_DISCARD then null will be returned. C<hash> can be a valid pre-computed
+hash value, or 0 to ask for it to be computed.
+
+ SV* hv_delete_ent _((HV* tb, SV* key, I32 flags, U32 hash));
+
=item hv_exists
Returns a boolean indicating whether the specified hash key exists. The
@@ -1421,6 +1543,13 @@ C<klen> is the length of the key.
bool hv_exists _((HV* tb, char* key, U32 klen));
+=item hv_exists_ent
+
+Returns a boolean indicating whether the specified hash key exists. C<hash>
+can be a valid pre-computed hash value, or 0 to ask for it to be computed.
+
+ bool hv_exists_ent _((HV* tb, SV* key, U32 hash));
+
=item hv_fetch
Returns the SV which corresponds to the specified key in the hash. The
@@ -1430,6 +1559,18 @@ dereferencing it to a C<SV*>.
SV** hv_fetch _((HV* tb, char* key, U32 klen, I32 lval));
+=item hv_fetch_ent
+
+Returns the hash entry which corresponds to the specified key in the hash.
+C<hash> must be a valid pre-computed hash number for the given C<key>, or
+0 if you want the function to compute it. IF C<lval> is set then the
+fetch will be part of a store. Make sure the return value is non-null
+before accessing it. The return value when C<tb> is a tied hash
+is a pointer to a static location, so be sure to make a copy of the
+structure if you need to store it somewhere.
+
+ HE* hv_fetch_ent _((HV* tb, SV* key, I32 lval, U32 hash));
+
=item hv_iterinit
Prepares a starting point to traverse a hash table.
@@ -1443,6 +1584,14 @@ C<hv_iterinit>.
char* hv_iterkey _((HE* entry, I32* retlen));
+=item hv_iterkeysv
+
+Returns the key as an C<SV*> from the current position of the hash
+iterator. The return value will always be a mortal copy of the
+key. Also see C<hv_iterinit>.
+
+ SV* hv_iterkeysv _((HE* entry));
+
=item hv_iternext
Returns entries from a hash iterator. See C<hv_iterinit>.
@@ -1485,6 +1634,17 @@ original C<SV*>.
SV** hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash));
+=item hv_store_ent
+
+Stores C<val> in a hash. The hash key is specified as C<key>. The C<hash>
+parameter is the pre-computed hash value; if it is zero then Perl will
+compute it. The return value is the new hash entry so created. It will be
+null if the operation failed or if the entry was stored in a tied hash.
+Otherwise the contents of the return value can be accessed using the
+C<He???> macros described here.
+
+ HE* hv_store_ent _((HV* tb, SV* key, SV* val, U32 hash));
+
=item hv_undef
Undefines the hash.
diff --git a/pp_ctl.c b/pp_ctl.c
index de3c13b472..6eab4da34e 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1946,10 +1946,10 @@ OP *o;
{
int ret;
int oldrunlevel = runlevel;
- OP *oldop = op;
Sigjmp_buf oldtop;
op = o;
+ runlevel--; /* pretense */
Copy(top_env, oldtop, 1, Sigjmp_buf);
#ifdef DEBUGGING
assert(mustcatch == TRUE);
@@ -1960,7 +1960,6 @@ OP *o;
Copy(oldtop, top_env, 1, Sigjmp_buf);
runlevel = oldrunlevel;
mustcatch = TRUE;
- op = oldop;
Siglongjmp(top_env, ret);
/* NOTREACHED */
case 3:
@@ -1968,7 +1967,6 @@ OP *o;
PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
break;
}
- mustcatch = FALSE;
op = restartop;
restartop = 0;
/* FALL THROUGH */
@@ -1979,7 +1977,6 @@ OP *o;
Copy(oldtop, top_env, 1, Sigjmp_buf);
runlevel = oldrunlevel;
mustcatch = TRUE;
- op = oldop;
return Nullop;
}