Skip to content

Commit c798bb6

Browse files
authored
Merge pull request #2730 from DennisHeimbigner/filtervlen2.dmh
Explicitly suppress variable length type compression
2 parents c374536 + db772ce commit c798bb6

File tree

6 files changed

+153
-43
lines changed

6 files changed

+153
-43
lines changed

libdispatch/dfilter.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,9 @@ nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const un
126126
{
127127
int stat = NC_NOERR;
128128
NC* ncp;
129-
int fixedsize;
130-
nc_type xtype;
131129

132130
TRACE(nc_inq_var_filter);
133131
if((stat = NC_check_id(ncid,&ncp))) return stat;
134-
/* Get variable' type */
135-
if((stat = nc_inq_vartype(ncid,varid,&xtype))) return stat;
136-
/* If the variable's type is not fixed-size, then signal error */
137-
if((stat = NC4_inq_type_fixed_size(ncid, xtype, &fixedsize))) return stat;
138-
if(!fixedsize) {
139-
nclog(NCLOGWARN,"Filters cannot be applied to variable length data types.");
140-
return NC_NOERR; /* Deliberately suppress */
141-
}
142132
if((stat = ncp->dispatch->def_var_filter(ncid,varid,id,nparams,params))) goto done;
143133
done:
144134
return stat;

libhdf5/nc4hdf.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -914,11 +914,7 @@ var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid
914914
BAIL(NC_EFILTER);
915915
} else {
916916
herr_t code = H5Pset_filter(plistid, fi->filterid,
917-
#if 1
918-
H5Z_FLAG_MANDATORY,
919-
#else
920-
H5Z_FLAG_OPTIONAL,
921-
#endif
917+
H5Z_FLAG_OPTIONAL, /* always make optional so filters on vlens are ignored */
922918
fi->nparams, fi->params);
923919
if(code < 0)
924920
BAIL(NC_EFILTER);

libnczarr/zfilter.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,13 @@ ncz_hdf5_clear(NCZ_HDF5* h) {
130130

131131
typedef struct NCZ_Filter {
132132
int flags; /**< Flags describing state of this filter. */
133-
# define FLAG_VISIBLE 1 /* If set, then visible parameters are defined */
134-
# define FLAG_WORKING 2 /* If set, then WORKING parameters are defined */
135-
# define FLAG_CODEC 4 /* If set, then visbile parameters come from an existing codec string */
136-
# define FLAG_HDF5 8 /* If set, => visible parameters came from nc_def_var_filter */
137-
# define FLAG_NEWVISIBLE 16 /* If set, => visible parameters were modified */
138-
# define FLAG_INCOMPLETE 32 /* If set, => filter has no complete matching plugin */
133+
# define FLAG_VISIBLE 1 /* If set, then visible parameters are defined */
134+
# define FLAG_WORKING 2 /* If set, then WORKING parameters are defined */
135+
# define FLAG_CODEC 4 /* If set, then visbile parameters come from an existing codec string */
136+
# define FLAG_HDF5 8 /* If set, => visible parameters came from nc_def_var_filter */
137+
# define FLAG_NEWVISIBLE 16 /* If set, => visible parameters were modified */
138+
# define FLAG_INCOMPLETE 32 /* If set, => filter has no complete matching plugin */
139+
# define FLAG_SUPPRESS 64 /* If set, => filter should not be used (probably because variable is not fixed size */
139140
NCZ_HDF5 hdf5;
140141
NCZ_Codec codec;
141142
struct NCZ_Plugin* plugin; /**< Implementation of this filter. */
@@ -389,6 +390,12 @@ NCZ_addfilter(NC_FILE_INFO_T* file, NC_VAR_INFO_T* var, unsigned int id, size_t
389390
nclistpush((NClist*)var->filters, fi);
390391
}
391392

393+
/* If this variable is not fixed size, mark filter as suppressed */
394+
if(var->type_info->varsized) {
395+
fi->flags |= FLAG_SUPPRESS;
396+
nclog(NCLOGWARN,"Filters cannot be applied to variable length data types; ignored");
397+
}
398+
392399
if(!FILTERINCOMPLETE(fi)) {
393400
/* (over)write the HDF5 parameters */
394401
nullfree(fi->hdf5.visible.params);
@@ -870,6 +877,7 @@ fprintf(stderr,">>> current: alloc=%u used=%u buf=%p\n",(unsigned)current_alloc,
870877
if(encode) {
871878
for(i=0;i<nclistlength(chain);i++) {
872879
f = (struct NCZ_Filter*)nclistget(chain,i);
880+
if(f->flags & FLAG_SUPPRESS) continue; /* this filter should not be applied */
873881
ff = f->plugin->hdf5.filter;
874882
/* code can be simplified */
875883
next_alloc = current_alloc;
@@ -889,6 +897,7 @@ fprintf(stderr,">>> next: alloc=%u used=%u buf=%p\n",(unsigned)next_alloc,(unsig
889897
/* Apply in reverse order */
890898
for(i=nclistlength(chain)-1;i>=0;i--) {
891899
f = (struct NCZ_Filter*)nclistget(chain,i);
900+
if(f->flags & FLAG_SUPPRESS) continue; /* this filter should not be applied */
892901
ff = f->plugin->hdf5.filter;
893902
/* code can be simplified */
894903
next_alloc = current_alloc;

nc_test4/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ endif
8181
if USE_HDF5
8282
if ENABLE_FILTER_TESTING
8383
extradir =
84-
check_PROGRAMS += test_filter test_filter_misc test_filter_order test_filter_repeat test_filter_vlen
84+
check_PROGRAMS += test_filter test_filter_misc test_filter_order test_filter_repeat
8585
check_PROGRAMS += tst_multifilter tst_filter_vlen
8686
TESTS += tst_filter.sh
8787
TESTS += tst_specific_filters.sh

nc_test4/tst_filter_vlen.c

Lines changed: 134 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@
1717

1818
#undef DEBUG
1919

20-
#ifndef H5Z_FILTER_BZIP2
21-
#define H5Z_FILTER_BZIP2 307
22-
#endif
23-
24-
#define TEST_ID 32768
20+
#define FILTER_ID 1 /*deflate*/
2521

2622
#define MAXERRS 8
2723

@@ -51,8 +47,7 @@ static int nerrs = 0;
5147

5248
static int ncid, varid;
5349
static int dimids[MAXDIMS];
54-
static float* array = NULL;
55-
static float* expected = NULL;
50+
static char** array = NULL;
5651

5752
/* Forward */
5853
static int test_test1(void);
@@ -100,26 +95,142 @@ defvar(nc_type xtype)
10095
return NC_NOERR;
10196
}
10297

98+
static int
99+
reopen(void)
100+
{
101+
size_t i;
102+
103+
CHECK(nc_open(testfile, NC_NETCDF4, &ncid));
104+
for(i=0;i<ndims;i++) {
105+
char dimname[1024];
106+
snprintf(dimname,sizeof(dimname),"dim%u",(unsigned)i);
107+
CHECK(nc_inq_dimid(ncid, dimname, &dimids[i]));
108+
CHECK(nc_inq_dim(ncid, dimids[i], NULL, &dimsize[i]));
109+
}
110+
CHECK(nc_inq_varid(ncid, "var", &varid));
111+
return NC_NOERR;
112+
}
113+
114+
115+
116+
/* Test that a filter is a variable length var is defined */
103117
static int
104118
test_test1(void)
105119
{
106120
int ok = 1;
107-
int id = -1;
108-
size_t nparams;
121+
size_t nfilters = 0;
122+
unsigned filterids[64];
123+
unsigned params[NPARAMS] = {5};
124+
size_t nparams = 0;
109125

110-
reset();
111126
fprintf(stderr,"test4: filter on a variable length type.\n");
112127
create();
113128
defvar(NC_STRING);
114129
/* Do explicit filter; should never fail, but may produce log warning */
115-
CHECK(nc_def_var_filter(ncid,varid,H5Z_FILTER_BZIP2,0,NULL));
130+
CHECK(nc_def_var_filter(ncid,varid,FILTER_ID,1,params));
116131
/* Now see if filter was defined or not */
117-
CHECK(nc_inq_var_filter(ncid,varid,&id,&nparams,NULL));
118-
if(id > 0) {
119-
fprintf(stderr,"*** id=%d\n",id);
132+
memset(filterids,0,sizeof(filterids));
133+
params[0] = 5;
134+
CHECK(nc_inq_var_filter_ids(ncid,varid,&nfilters,filterids));
135+
fprintf(stderr,"test_test1: nc_var_filter_ids: nfilters=%u filterids[0]=%d\n",(unsigned)nfilters,filterids[0]);
136+
if(nfilters != 1 && filterids[0] != FILTER_ID) {
137+
fprintf(stderr,"test_test1: nc_var_filter_ids: failed\n");
120138
ok = 0;
121139
}
122-
CHECK(nc_abort(ncid));
140+
params[0] = 0;
141+
CHECK(nc_inq_var_filter_info(ncid, varid, filterids[0], &nparams, params));
142+
fprintf(stderr,"test_test1: nc_inq_var_filter_info: nparams=%u params[0]=%u\n",(unsigned)nparams,(unsigned)params[0]);
143+
return ok;
144+
}
145+
146+
/* Test that a filter on a variable length var is suppressed */
147+
static int
148+
test_test2(void)
149+
{
150+
int stat = NC_NOERR;
151+
int ok = 1;
152+
size_t i;
153+
154+
reset();
155+
fprintf(stderr,"test4: write with filter on a variable length type.\n");
156+
/* generate the data to write */
157+
for(i=0;i<actualproduct;i++) {
158+
char digits[64];
159+
snprintf(digits,sizeof(digits),"%u",(unsigned)i);
160+
array[i] = strdup(digits);
161+
}
162+
/* write the data */
163+
if((stat=nc_put_var(ncid,varid,(void*)array))) {
164+
fprintf(stderr,"test_test2: nc_put_var: error = (%d)%s\n",stat,nc_strerror(stat));
165+
ok = 0;
166+
goto done;
167+
}
168+
/* re-read the data */
169+
reset();
170+
if((stat=nc_get_var(ncid,varid,(void*)array))) {
171+
fprintf(stderr,"test_test2: nc_get_var: error = (%d)%s\n",stat,nc_strerror(stat));
172+
ok = 0;
173+
goto done;
174+
}
175+
/* verify the data */
176+
for(i=0;i<actualproduct;i++) {
177+
unsigned value = 0xffffffff;
178+
if(array[i] != NULL)
179+
sscanf(array[i],"%u",&value);
180+
if(array[i] == NULL || i != value) {
181+
fprintf(stderr,"test_test2: nc_get_var: value mismatch at %u\n",(unsigned)i);
182+
ok = 0;
183+
goto done;
184+
}
185+
}
186+
nc_close(ncid);
187+
done:
188+
return ok;
189+
}
190+
191+
/* Test that a filter on a variable length var is suppressed */
192+
static int
193+
test_test3(void)
194+
{
195+
int stat = NC_NOERR;
196+
int ok = 1;
197+
size_t i,nfilters;
198+
unsigned filterids[64];
199+
200+
fprintf(stderr,"test4: re-open variable with filter on a variable length type and verify state.\n");
201+
202+
reopen();
203+
204+
/* verify filter state */
205+
memset(filterids,0,sizeof(filterids));
206+
CHECK(nc_inq_var_filter_ids(ncid,varid,&nfilters,filterids));
207+
fprintf(stderr,"test_test3: nc_var_filter_ids: nfilters=%u filterids[0]=%d\n",(unsigned)nfilters,filterids[0]);
208+
if(nfilters != 1 && filterids[0] != FILTER_ID) {
209+
fprintf(stderr,"test_test3: nc_var_filter_ids: failed\n");
210+
ok = 0;
211+
goto done;
212+
}
213+
214+
/* re-read the data */
215+
reset();
216+
if((stat=nc_get_var(ncid,varid,(void*)array))) {
217+
fprintf(stderr,"test_test3: nc_get_var: error = (%d)%s\n",stat,nc_strerror(stat));
218+
ok = 0;
219+
goto done;
220+
}
221+
/* verify the data */
222+
for(i=0;i<actualproduct;i++) {
223+
unsigned value = 0xffffffff;
224+
if(array[i] != NULL)
225+
sscanf(array[i],"%u",&value);
226+
if(array[i] == NULL || i != value) {
227+
fprintf(stderr,"test_test3: nc_get_var: value mismatch at %u\n",(unsigned)i);
228+
ok = 0;
229+
goto done;
230+
}
231+
}
232+
nc_close(ncid);
233+
done:
123234
return ok;
124235
}
125236

@@ -129,7 +240,11 @@ test_test1(void)
129240
static void
130241
reset()
131242
{
132-
memset(array,0,sizeof(float)*actualproduct);
243+
size_t i;
244+
for(i=0;i<actualproduct;i++) {
245+
if(array[i]) free(array[i]);
246+
array[i] = NULL;
247+
}
133248
}
134249

135250
static void
@@ -153,8 +268,7 @@ init(int argc, char** argv)
153268
}
154269
}
155270
/* Allocate max size */
156-
array = (float*)calloc(1,sizeof(float)*actualproduct);
157-
expected = (float*)calloc(1,sizeof(float)*actualproduct);
271+
array = (char**)calloc(1,sizeof(char*)*actualproduct);
158272
}
159273

160274
/**************************************************/
@@ -167,6 +281,8 @@ main(int argc, char **argv)
167281
#endif
168282
init(argc,argv);
169283
if(!test_test1()) ERRR;
284+
if(!test_test2()) ERRR;
285+
if(!test_test3()) ERRR;
170286
fprintf(stderr,"*** %s\n",(nerrs > 0 ? "FAILED" : "PASS"));
171287
exit(nerrs > 0?1:0);
172288
}

nc_test4/tst_filter_vlen.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#!/bin/bash
22

3-
# Test the filter install
4-
# This cannot be run as a regular test
5-
# because installation will not have occurred
3+
# Test filters on non-fixed size variables.
64

75
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
86
. ../test_common.sh
@@ -95,6 +93,7 @@ if test "x$TESTNCZARR" = x1 ; then
9593
testset file
9694
if test "x$FEATURE_NCZARR_ZIP" = xyes ; then testset zip ; fi
9795
if test "x$FEATURE_S3TESTS" = xyes ; then testset s3 ; fi
96+
if test "x$FEATURE_S3TESTS" = xyes ; then s3sdkdelete "/${S3ISOPATH}" ; fi # Cleanup
9897
else
9998
testset nc
10099
fi

0 commit comments

Comments
 (0)