Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys - Implement



details:   https://anonhg.NetBSD.org/src/rev/20b671ae4346
branches:  trunk
changeset: 518934:20b671ae4346
user:      lukem <lukem%NetBSD.org@localhost>
date:      Sat Dec 08 04:09:59 2001 +0000

description:
- Implement
        uint32_t namei_hash(const char *p, const char **ep)
  which determines the equivalent MI hash32_str() hash for p.
  If *ep != NULL, calculate the hash to the character before ep.
  If *ep == NULL, calculate the has to the first / or NUL found, and
  point *ep to that location.
- Use namei_hash() to calculate cn_hash in lookup() and relookup().
  Hash distribution goes from 35-40% to 55-70%, with similar profiled
  time spent in cache_lookup() and cache_enter() on my P3-600.
- Use namei_hash() to calculate cn_hash in nfs_readdirplusrpc(),
  insetad of homegrown code (that differed from that in lookup() !)
  namei_hash() has better spread and is faster than previous code
  (which used a non-constant multiplication).

diffstat:

 sys/kern/vfs_lookup.c |  44 ++++++++++++++++++++++++++++++++++++--------
 sys/nfs/nfs_vnops.c   |  15 ++++++++-------
 sys/sys/namei.h       |   3 ++-
 3 files changed, 46 insertions(+), 16 deletions(-)

diffs (158 lines):

diff -r 54f5e71fb583 -r 20b671ae4346 sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c     Sat Dec 08 04:09:56 2001 +0000
+++ b/sys/kern/vfs_lookup.c     Sat Dec 08 04:09:59 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_lookup.c,v 1.38 2001/11/12 15:25:39 lukem Exp $    */
+/*     $NetBSD: vfs_lookup.c,v 1.39 2001/12/08 04:09:59 lukem Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.38 2001/11/12 15:25:39 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.39 2001/12/08 04:09:59 lukem Exp $");
 
 #include "opt_ktrace.h"
 
@@ -53,8 +53,9 @@
 #include <sys/vnode.h>
 #include <sys/mount.h>
 #include <sys/errno.h>
+#include <sys/filedesc.h>
+#include <sys/hash.h>
 #include <sys/malloc.h>
-#include <sys/filedesc.h>
 #include <sys/proc.h>
 
 #ifdef KTRACE
@@ -236,6 +237,34 @@
 }
 
 /*
+ * Determine the namei hash (for cn_hash) for name.
+ * If *ep != NULL, hash from name to ep-1.
+ * If *ep == NULL, hash from name until the first NUL or '/', and
+ * return the location of this termination character in *ep.
+ *
+ * This function returns an equivalent hash to the MI hash32_strn().
+ * The latter isn't used because in the *ep == NULL case, determining
+ * the length of the string to the first NUL or `/' and then calling
+ * hash32_strn() involves unnecessary double-handling of the data.
+ */
+uint32_t
+namei_hash(const char *name, const char **ep)
+{
+       uint32_t        hash;
+
+       hash = HASH32_STR_INIT;
+       if (*ep != NULL) {
+               for (; name < *ep; name++)
+                       hash = hash * 33 + *(uint8_t *)name;
+       } else {
+               for (; *name != '\0' && *name != '/'; name++)
+                       hash = hash * 33 + *(uint8_t *)name;
+               *ep = name;
+       }
+       return (hash + (hash >> 5));
+}
+
+/*
  * Search a pathname.
  * This is a very central and rather complicated routine.
  *
@@ -349,9 +378,8 @@
         * responsibility for freeing the pathname buffer.
         */
        cnp->cn_consume = 0;
-       cnp->cn_hash = 0;
-       for (cp = cnp->cn_nameptr; *cp != '\0' && *cp != '/'; cp++)
-               cnp->cn_hash += (unsigned char)*cp;
+       cp = NULL;
+       cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp);
        cnp->cn_namelen = cp - cnp->cn_nameptr;
        if (cnp->cn_namelen > NAME_MAX) {
                error = ENAMETOOLONG;
@@ -638,8 +666,8 @@
         * responsibility for freeing the pathname buffer.
         */
 #ifdef NAMEI_DIAGNOSTIC
-       for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
-               newhash += (unsigned char)*cp;
+       cp = NULL;
+       newhash = namei_hash(cnp->cn_nameptr, &cp);
        if (newhash != cnp->cn_hash)
                panic("relookup: bad hash");
        if (cnp->cn_namelen != cp - cnp->cn_nameptr)
diff -r 54f5e71fb583 -r 20b671ae4346 sys/nfs/nfs_vnops.c
--- a/sys/nfs/nfs_vnops.c       Sat Dec 08 04:09:56 2001 +0000
+++ b/sys/nfs/nfs_vnops.c       Sat Dec 08 04:09:59 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_vnops.c,v 1.146 2001/12/04 18:38:09 christos Exp $ */
+/*     $NetBSD: nfs_vnops.c,v 1.147 2001/12/08 04:10:00 lukem Exp $    */
 
 /*
  * Copyright (c) 1989, 1993
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.146 2001/12/04 18:38:09 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.147 2001/12/08 04:10:00 lukem Exp $");
 
 #include "opt_nfs.h"
 #include "opt_uvmhist.h"
@@ -62,6 +62,7 @@
 #include <sys/vnode.h>
 #include <sys/dirent.h>
 #include <sys/fcntl.h>
+#include <sys/hash.h>
 #include <sys/lockf.h>
 #include <sys/stat.h>
 #include <sys/unistd.h>
@@ -2377,7 +2378,6 @@
        struct componentname *cnp = &ndp->ni_cnd;
        struct nfsmount *nmp = VFSTONFS(vp->v_mount);
        struct nfsnode *dnp = VTONFS(vp), *np;
-       const unsigned char *hcp;
        nfsfh_t *fhp;
        u_quad_t fileno;
        int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
@@ -2522,14 +2522,15 @@
                                        newvp = NFSTOV(np);
                                }
                                if (!error) {
+                                   const char *cp;
+
                                    nfs_loadattrcache(&newvp, &fattr, 0);
                                    dp->d_type =
                                        IFTODT(VTTOIF(np->n_vattr->va_type));
                                    ndp->ni_vp = newvp;
-                                   cnp->cn_hash = 0;
-                                   for (hcp = cnp->cn_nameptr, i = 1; i <= len;
-                                       i++, hcp++)
-                                       cnp->cn_hash += *hcp * i;
+                                   cp = cnp->cn_nameptr + cnp->cn_namelen;
+                                   cnp->cn_hash =
+                                       namei_hash(cnp->cn_nameptr, &cp);
                                    if (cnp->cn_namelen <= NCHNAMLEN)
                                        cache_enter(ndp->ni_dvp, ndp->ni_vp,
                                                    cnp);
diff -r 54f5e71fb583 -r 20b671ae4346 sys/sys/namei.h
--- a/sys/sys/namei.h   Sat Dec 08 04:09:56 2001 +0000
+++ b/sys/sys/namei.h   Sat Dec 08 04:09:59 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: namei.h,v 1.24 2001/12/06 04:02:22 lukem Exp $ */
+/*     $NetBSD: namei.h,v 1.25 2001/12/08 04:10:00 lukem Exp $ */
 
 /*
  * Copyright (c) 1985, 1989, 1991, 1993
@@ -184,6 +184,7 @@
 #define        PNBUF_PUT(pnb)  pool_cache_put(&pnbuf_cache, (pnb))
 
 int    namei __P((struct nameidata *ndp));
+uint32_t namei_hash __P((const char *, const char **));
 int    lookup __P((struct nameidata *ndp));
 int    relookup __P((struct vnode *dvp, struct vnode **vpp,
                      struct componentname *cnp));



Home | Main Index | Thread Index | Old Index