diff --git a/libsrc/Makefile.am b/libsrc/Makefile.am index 4e3ea3dce..b6ae1c30d 100644 --- a/libsrc/Makefile.am +++ b/libsrc/Makefile.am @@ -34,7 +34,7 @@ netcdf.3: $(top_srcdir)/man4/netcdf.m4 libnetcdf3_la_SOURCES = nc.h error3.c libvers.c string.c v1hpg.c fbits.h ncio.h \ onstack.h rnd.h utf8proc.c utf8proc.h utf8proc_data.h nclistmgr.c \ putget.m4 attr.m4 nc3dispatch.c nc3dispatch.h nc.c var.c dim.c ncx.m4 \ -ncx.h +ncx.h lookup3.c # Does the user want to use ffio or posixio? if USE_FFIO diff --git a/libsrc/dim.c b/libsrc/dim.c index 6c264d28f..c9573c0cc 100644 --- a/libsrc/dim.c +++ b/libsrc/dim.c @@ -37,6 +37,7 @@ new_x_NC_dim(NC_string *name) return NULL; dimp->name = name; + dimp->hash = hash_fast(name->cp, strlen(name->cp)); dimp->size = 0; return(dimp); @@ -126,7 +127,7 @@ NC_finddim(const NC_dimarray *ncap, const char *uname, NC_dim **dimpp) { int dimid; - size_t slen; + uint32_t shash; NC_dim ** loc; char *name; @@ -142,11 +143,11 @@ NC_finddim(const NC_dimarray *ncap, const char *uname, NC_dim **dimpp) name = (char *)utf8proc_NFC((const unsigned char *)uname); if(name == NULL) return NC_ENOMEM; - slen = strlen(name); + shash = hash_fast(name, strlen(name)); for(; (size_t) dimid < ncap->nelems - && (strlen((*loc)->name->cp) != slen - || strncmp((*loc)->name->cp, name, slen) != 0); + && ((*loc)->hash != shash + || strncmp((*loc)->name->cp, name, strlen(name)) != 0); dimid++, loc++) { /*EMPTY*/ @@ -469,6 +470,7 @@ NC3_rename_dim( int ncid, int dimid, const char *unewname) if(newStr == NULL) return NC_ENOMEM; dimp->name = newStr; + dimp->hash = hash_fast(newStr->cp, strlen(newStr->cp)); free_NC_string(old); return NC_NOERR; } diff --git a/libsrc/nc.h b/libsrc/nc.h index c6a9b6a4d..2161d4d14 100644 --- a/libsrc/nc.h +++ b/libsrc/nc.h @@ -11,6 +11,11 @@ */ #include #include /* size_t */ +#ifndef HAVE_STDINT_H +# include "pstdint.h" /* attempts to define uint32_t etc portably */ +#else +# include +#endif /* HAVE_STDINT_H */ #include /* off_t */ #ifdef USE_PARALLEL #include @@ -80,6 +85,7 @@ set_NC_string(NC_string *ncstrp, const char *str); typedef struct { /* all xdr'd */ NC_string *name; + uint32_t hash; size_t size; } NC_dim; @@ -178,6 +184,7 @@ typedef struct NC_var { off_t *dsizes; /* compiled info: the right to left product of shape */ /* below gets xdr'd */ NC_string *name; + uint32_t hash; /* next two: formerly NC_iarray *assoc */ /* user definition */ size_t ndims; /* assoc->count */ int *dimids; /* assoc->value */ @@ -195,6 +202,13 @@ typedef struct NC_vararray { NC_var **value; } NC_vararray; +/* Begin defined in lookup3.c */ + +extern uint32_t +hash_fast(const void *key, size_t length); + +/* End defined in lookup3.c */ + /* Begin defined in var.c */ extern void diff --git a/libsrc/var.c b/libsrc/var.c index bc1fafb63..8bcbb8b9b 100644 --- a/libsrc/var.c +++ b/libsrc/var.c @@ -65,6 +65,7 @@ new_x_NC_var( (void) memset(varp, 0, sz); varp->name = strp; varp->ndims = ndims; + varp->hash = hash_fast(strp->cp, strlen(strp->cp)); if(ndims != 0) { @@ -321,7 +322,7 @@ int NC_findvar(const NC_vararray *ncap, const char *uname, NC_var **varpp) { NC_var **loc; - size_t slen; + uint32_t shash; int varid; char *name; @@ -336,12 +337,12 @@ NC_findvar(const NC_vararray *ncap, const char *uname, NC_var **varpp) name = (char *)utf8proc_NFC((const unsigned char *)uname); if(name == NULL) return NC_ENOMEM; - slen = strlen(name); + shash = hash_fast(name, strlen(name)); for(varid = 0; (size_t) varid < ncap->nelems; varid++, loc++) { - if(strlen((*loc)->name->cp) == slen && - strncmp((*loc)->name->cp, name, slen) == 0) + if((*loc)->hash == shash && + strncmp((*loc)->name->cp, name, strlen(name)) == 0) { if(varpp != NULL) *varpp = *loc; @@ -714,12 +715,14 @@ NC3_rename_var(int ncid, int varid, const char *unewname) if(newStr == NULL) return(-1); varp->name = newStr; + varp->hash = hash_fast(newStr->cp, strlen(newStr->cp)); free_NC_string(old); return NC_NOERR; } /* else, not in define mode */ status = set_NC_string(varp->name, newname); + varp->hash = hash_fast(newname, strlen(newname)); free(newname); if(status != NC_NOERR) return status;