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:
Dennis Heimbigner 2013-07-27 20:20:13 +00:00
parent 0d8969da1c
commit fcecd1a2bc
9 changed files with 76 additions and 44 deletions

2
cf
View File

@ -6,7 +6,7 @@ if test $# != 0 ; then
cmds=$@
fi
HDF5=1
#HDF5=1
DAP=1
#PNETCDF=1
#HDF4=1

View File

@ -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 */

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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);

View File

@ -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 \

View File

@ -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

View File

@ -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);