mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-04-12 18:10:24 +08:00
1. The duplicate name checking in oc2 was
effectively o(n cubed); modified to be o(n squared). 2. If the list of prefetched variables is too long, (something on the order of 400 variables), then the server may reject it. Modified code so that in the case that the set of prefetch'd vars is the in fact all variables, it does not create a long request. This does not actually solve the problem if the prefetch list is long, but not all inclusive.
This commit is contained in:
parent
0d8969da1c
commit
fcecd1a2bc
2
cf
2
cf
@ -6,7 +6,7 @@ if test $# != 0 ; then
|
||||
cmds=$@
|
||||
fi
|
||||
|
||||
HDF5=1
|
||||
#HDF5=1
|
||||
DAP=1
|
||||
#PNETCDF=1
|
||||
#HDF4=1
|
||||
|
@ -86,13 +86,13 @@ NCerror
|
||||
prefetchdata3(NCDAPCOMMON* nccomm)
|
||||
{
|
||||
int i;
|
||||
NCFLAGS flags;
|
||||
NCerror ncstat = NC_NOERR;
|
||||
NClist* allvars = nccomm->cdf.ddsroot->tree->varnodes;
|
||||
DCEconstraint* urlconstraint = nccomm->oc.dapconstraint;
|
||||
NClist* vars = nclistnew();
|
||||
NCcachenode* cache = NULL;
|
||||
DCEconstraint* newconstraint = NULL;
|
||||
int isnc4 = FLAGSET(nccomm->controls,NCF_NC4);
|
||||
|
||||
if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) {
|
||||
/* If we cannot constrain and caching is enabled,
|
||||
@ -121,7 +121,7 @@ prefetchdata3(NCDAPCOMMON* nccomm)
|
||||
continue;
|
||||
|
||||
/* Should be prefetchable */
|
||||
nclistpush(vars,(void*)var);
|
||||
nclistpush(vars,(void*)var);
|
||||
if(SHOWFETCH) {
|
||||
nclog(NCLOGDBG,"prefetch: %s",var->ncfullname);
|
||||
}
|
||||
@ -136,6 +136,7 @@ nclog(NCLOGDBG,"prefetch: %s",var->ncfullname);
|
||||
|
||||
/* Create a single constraint consisting of the projections for the variables;
|
||||
each projection is whole variable. The selections are passed on as is.
|
||||
The exception is if we are prefetching everything.
|
||||
*/
|
||||
|
||||
newconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
|
||||
@ -143,7 +144,7 @@ nclog(NCLOGDBG,"prefetch: %s",var->ncfullname);
|
||||
newconstraint->selections = dceclonelist(urlconstraint->selections);
|
||||
|
||||
for(i=0;i<nclistlength(vars);i++) {
|
||||
CDFnode* var = (CDFnode*)nclistget(vars,i);
|
||||
CDFnode* var = (CDFnode*)nclistget(vars,i);
|
||||
DCEprojection* varprojection;
|
||||
/* convert var to a projection */
|
||||
ncstat = dapvar2projection(var,&varprojection);
|
||||
@ -155,7 +156,10 @@ char* s = dumpprojections(newconstraint->projections);
|
||||
LOG1(NCLOGNOTE,"prefetch.final: %s",s);
|
||||
nullfree(s);
|
||||
}
|
||||
ncstat = buildcachenode34(nccomm,newconstraint,vars,&cache,!isnc4);
|
||||
|
||||
flags = NCF_PREFETCH;
|
||||
if(nclistlength(allvars) == nclistlength(vars)) flags |= NCF_PREFETCH_ALL;
|
||||
ncstat = buildcachenode34(nccomm,newconstraint,vars,&cache,flags);
|
||||
newconstraint = NULL; /* buildcachenode34 takes control of newconstraint */
|
||||
if(ncstat) goto done;
|
||||
cache->wholevariable = 1; /* All prefetches are whole variable */
|
||||
@ -194,7 +198,7 @@ buildcachenode34(NCDAPCOMMON* nccomm,
|
||||
DCEconstraint* constraint,
|
||||
NClist* varlist,
|
||||
NCcachenode** cachep,
|
||||
int isprefetch)
|
||||
NCFLAGS flags)
|
||||
{
|
||||
NCerror ncstat = NC_NOERR;
|
||||
OCerror ocstat = OC_NOERR;
|
||||
@ -203,8 +207,13 @@ buildcachenode34(NCDAPCOMMON* nccomm,
|
||||
CDFnode* dxdroot = NULL;
|
||||
NCcachenode* cachenode = NULL;
|
||||
char* ce = NULL;
|
||||
int isprefetch = 0;
|
||||
|
||||
ce = buildconstraintstring3(constraint);
|
||||
if((flags & NCF_PREFETCH) != 0)
|
||||
isprefetch = 1;
|
||||
|
||||
if((flags & NCF_PREFETCH_ALL) == 0)
|
||||
ce = buildconstraintstring3(constraint);
|
||||
|
||||
ocstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot);
|
||||
nullfree(ce);
|
||||
@ -221,7 +230,7 @@ buildcachenode34(NCDAPCOMMON* nccomm,
|
||||
|
||||
/* create the cache node */
|
||||
cachenode = createnccachenode();
|
||||
cachenode->prefetch = isprefetch;
|
||||
cachenode->isprefetch = isprefetch;
|
||||
cachenode->vars = nclistclone(varlist);
|
||||
cachenode->datadds = dxdroot;
|
||||
/* Give the constraint over to the cachenode */
|
||||
|
@ -511,7 +511,7 @@ dumpcachenode(NCcachenode* node)
|
||||
buf = ncbytesnew();
|
||||
result = buildconstraintstring3(node->constraint);
|
||||
snprintf(tmp,sizeof(tmp),"cachenode%s(%lx){size=%lu; constraint=%s; vars=",
|
||||
node->prefetch?"*":"",
|
||||
node->isprefetch?"*":"",
|
||||
(unsigned long)node,
|
||||
(unsigned long)node->xdrsize,
|
||||
result);
|
||||
|
12
libdap2/env
12
libdap2/env
@ -1,8 +1,8 @@
|
||||
PARMS=""; ARGS=""; CON="" ; CE=""; OCON="" ; VAR=""; SHARP='#'
|
||||
alias q0=;alias qq=;alias qv=;alias q=;alias qh=;alias qqh=;alias qall=;alias qv=;alias qo=;
|
||||
|
||||
#TOP="/home/dmh/mach/trunk"
|
||||
TOP="/cygdrive/f/svn/trunk"
|
||||
TOP="/home/dmh/mach/trunk"
|
||||
#TOP="/cygdrive/f/svn/trunk"
|
||||
#TOP="/cygdrive/c/Users/dmh/svn/trunk"
|
||||
|
||||
#PROG=./ncd
|
||||
@ -10,8 +10,11 @@ PROG="$TOP/ncdump/ncdump"
|
||||
|
||||
P=`pwd`
|
||||
|
||||
F="http://portal.nersc.gov/pydap/20C_Reanalysis_ensemble/analysis.derived/pwat/pwat_1928.daily.nc"
|
||||
#CON='station&station="Anacapa_Landing_Cove"'
|
||||
#F='http://colossus.dl.stevens-tech.edu/thredds/dodsC/fmrc/NYBight/NYHOPS_Forecast_Collection_for_the_New_York_Bight_best.ncd'
|
||||
#CON='xpos'
|
||||
#VAR=data
|
||||
|
||||
F="http://opendap.deltares.nl/opendap/test/testNcWithManyVariables/test3000.nc"
|
||||
|
||||
PARMS="log"
|
||||
#PARMS="${PARMS}&netcdf3"
|
||||
@ -45,6 +48,7 @@ UALL="$U${PARMS}"
|
||||
#ARGS="-h $ARGS"
|
||||
#ARGS="-w $ARGS"
|
||||
#ARGS="-c $ARGS"
|
||||
if test "x$VAR" != "x" ; then ARGS="$ARGS -v $VAR" ; fi
|
||||
|
||||
VARGS="--leak-check=full"
|
||||
|
||||
|
@ -372,6 +372,7 @@ fprintf(stderr,"getvarx: FETCHPART: fetchconstraint: %s\n",dumpconstraint(fetchc
|
||||
will also fetch the corresponding datadds.
|
||||
*/
|
||||
ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0);
|
||||
|
||||
fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/
|
||||
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
|
||||
} break;
|
||||
|
@ -77,6 +77,7 @@ typedef unsigned int NCFLAGS;
|
||||
#define NCF_WHOLEVAR (0x0100) /* retrieve only whole variables (as opposed to partial variable) into cache */
|
||||
#define NCF_PREFETCH (0x0200) /* Cache prefetch enabled/disabled */
|
||||
#define NCF_PREFETCH_EAGER (0x0400) /* Do eager prefetch; 0=>lazy */
|
||||
#define NCF_PREFETCH_ALL (0x0800) /* Prefetch all variables */
|
||||
|
||||
/* Define all the default on flags */
|
||||
#define DFALT_ON_FLAGS (NCF_CACHE|NCF_PREFETCH)
|
||||
@ -91,10 +92,13 @@ struct NCTMODEL {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/* Define the cache control flags */
|
||||
|
||||
|
||||
/* Detail information about each cache item */
|
||||
typedef struct NCcachenode {
|
||||
int wholevariable; /* does this cache node only have wholevariables? */
|
||||
int prefetch; /* is this the prefetch cache entry? */
|
||||
int isprefetch;
|
||||
off_t xdrsize;
|
||||
DCEconstraint* constraint; /* as used to create this node */
|
||||
NClist* vars; /* vars potentially covered by this cache node */
|
||||
@ -322,7 +326,7 @@ extern NCerror buildcachenode34(NCDAPCOMMON*,
|
||||
DCEconstraint* constraint,
|
||||
NClist* varlist,
|
||||
NCcachenode** cachep,
|
||||
int isprefetch);
|
||||
NCFLAGS flags);
|
||||
extern NCcachenode* createnccachenode(void);
|
||||
extern void freenccachenode(NCDAPCOMMON*, NCcachenode* node);
|
||||
extern NCcache* createnccache(void);
|
||||
|
@ -1,6 +1,6 @@
|
||||
THISDIR=../oc2
|
||||
#OCDIR=/home/dmh/svn/oc2.0
|
||||
OCDIR=f:/svn/oc2.0
|
||||
OCDIR=/home/dmh/svn/oc2.0
|
||||
#OCDIR=f:/svn/oc2.0
|
||||
|
||||
# Make consistent with Makefile.am
|
||||
SRC=oc.c \
|
||||
|
@ -13,7 +13,7 @@ static int isglobalname(const char* name);
|
||||
static int isdodsname(const char* name);
|
||||
static OCnode* newocnode(char* name, OCtype octype, DAPparsestate* state);
|
||||
static OCtype octypefor(Object etype);
|
||||
static char* scopeduplicates(OClist* list);
|
||||
static OClist* scopeduplicates(OClist* list);
|
||||
static int check_int32(char* val, long* value);
|
||||
|
||||
|
||||
@ -43,12 +43,13 @@ dap_datasetbody(DAPparsestate* state, Object name, Object decls)
|
||||
{
|
||||
OCnode* root = newocnode((char*)name,OC_Dataset,state);
|
||||
char* dupname = NULL;
|
||||
dupname = scopeduplicates((OClist*)decls);
|
||||
if(dupname != NULL) {
|
||||
OClist* dups = scopeduplicates((OClist*)decls);
|
||||
if(dups != NULL) {
|
||||
/* Sometimes, some servers (i.e. Thredds)
|
||||
return a dds with duplicate field names
|
||||
at the dataset level; simulate an errorbody response
|
||||
*/
|
||||
ocnodes_free(dups);
|
||||
dap_parse_error(state,"Duplicate dataset field names: %s",name,dupname);
|
||||
state->error = OC_ENAMEINUSE;
|
||||
return (Object)NULL;
|
||||
@ -65,7 +66,16 @@ dap_datasetbody(DAPparsestate* state, Object name, Object decls)
|
||||
Object
|
||||
dap_attributebody(DAPparsestate* state, Object attrlist)
|
||||
{
|
||||
OCnode* node = newocnode(NULL,OC_Attributeset,state);
|
||||
OCnode* node;
|
||||
/* Check for and remove attribute duplicates */
|
||||
OClist* dups = scopeduplicates((OClist*)attrlist);
|
||||
if(dups != NULL) {
|
||||
ocnodes_free(dups);
|
||||
dap_parse_error(state,"Duplicate attribute names in same scope");
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
return NULL;
|
||||
}
|
||||
node = newocnode(NULL,OC_Attributeset,state);
|
||||
OCASSERT((state->root == NULL));
|
||||
state->root = node;
|
||||
/* make sure to cross link */
|
||||
@ -147,15 +157,8 @@ dap_attrlist(DAPparsestate* state, Object attrlist, Object attrtuple)
|
||||
if(alist == NULL)
|
||||
alist = oclistnew();
|
||||
else {
|
||||
char* dupname;
|
||||
if(attrtuple != NULL) {/* NULL=>alias encountered, ignore */
|
||||
oclistpush(alist,(void*)attrtuple);
|
||||
if((dupname=scopeduplicates(alist))!=NULL) {
|
||||
dap_parse_error(state,"Duplicate attribute names in same scope: %s",dupname);
|
||||
/* Remove this attribute */
|
||||
oclistpop(alist);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
}
|
||||
}
|
||||
}
|
||||
return alist;
|
||||
@ -270,9 +273,10 @@ Object
|
||||
dap_makestructure(DAPparsestate* state, Object name, Object dimensions, Object fields)
|
||||
{
|
||||
OCnode* node;
|
||||
char* dupname;
|
||||
if((dupname=scopeduplicates((OClist*)fields))!= NULL) {
|
||||
dap_parse_error(state,"Duplicate structure field names in same scope: %s.%s",(char*)name,dupname);
|
||||
OClist* dups = scopeduplicates((OClist*)fields);
|
||||
if(dups != NULL) {
|
||||
ocnodes_free(dups);
|
||||
dap_parse_error(state,"Duplicate structure field names in same structure: %s",(char*)name);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
return (Object)NULL;
|
||||
}
|
||||
@ -287,9 +291,10 @@ Object
|
||||
dap_makesequence(DAPparsestate* state, Object name, Object members)
|
||||
{
|
||||
OCnode* node;
|
||||
char* dupname;
|
||||
if((dupname=scopeduplicates((OClist*)members)) != NULL) {
|
||||
dap_parse_error(state,"Duplicate sequence member names in same scope: %s.%s",(char*)name,dupname);
|
||||
OClist* dups = scopeduplicates((OClist*)members);
|
||||
if(dups != NULL) {
|
||||
ocnodes_free(dups);
|
||||
dap_parse_error(state,"Duplicate sequence member names in same sequence: %s",(char*)name);
|
||||
return (Object)NULL;
|
||||
}
|
||||
node = newocnode(name,OC_Sequence,state);
|
||||
@ -303,9 +308,10 @@ dap_makegrid(DAPparsestate* state, Object name, Object arraydecl, Object mapdecl
|
||||
{
|
||||
OCnode* node;
|
||||
/* Check for duplicate map names */
|
||||
char* dupname;
|
||||
if((dupname=scopeduplicates((OClist*)mapdecls)) != NULL) {
|
||||
dap_parse_error(state,"Duplicate grid map names in same scope: %s.%s",(char*)name,dupname);
|
||||
OClist* dups = scopeduplicates((OClist*)mapdecls);
|
||||
if(dups != NULL) {
|
||||
ocnodes_free(dups);
|
||||
dap_parse_error(state,"Duplicate grid map names in same grid: %s",(char*)name);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
return (Object)NULL;
|
||||
}
|
||||
@ -392,19 +398,27 @@ check_int32(char* val, long* value)
|
||||
return ok;
|
||||
}
|
||||
|
||||
static char*
|
||||
static OClist*
|
||||
scopeduplicates(OClist* list)
|
||||
{
|
||||
unsigned int i,j;
|
||||
for(i=0;i<oclistlength(list);i++) {
|
||||
unsigned int len = oclistlength(list);
|
||||
OClist* dups = NULL;
|
||||
for(i=0;i<len;i++) {
|
||||
OCnode* io = (OCnode*)oclistget(list,i);
|
||||
for(j=i+1;j<oclistlength(list);j++) {
|
||||
retry:
|
||||
for(j=i+1;j<len;j++) {
|
||||
OCnode* jo = (OCnode*)oclistget(list,j);
|
||||
if(strcmp(io->name,jo->name)==0)
|
||||
return io->name;
|
||||
if(strcmp(io->name,jo->name)==0) {
|
||||
if(dups == NULL) dups = oclistnew();
|
||||
oclistpush(dups,jo);
|
||||
oclistremove(list,j);
|
||||
len--;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return dups;
|
||||
}
|
||||
|
||||
static OCtype
|
||||
|
@ -799,7 +799,7 @@ ocuridecodeonly(char* s, char* only)
|
||||
char* inptr;
|
||||
unsigned int c;
|
||||
|
||||
if(s == NULL) return NULL;
|
||||
if (s == NULL) return NULL;
|
||||
if(only == NULL) only = "";
|
||||
|
||||
slen = strlen(s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user