netcdf-c/unit_test/tst_xcache.c
Dennis Heimbigner d2316f866c Additional Fixes to NCZarr
Primary Fixes:
* Add a whole variable optimization -- used in the rare case that nc_get/put_vara covers the whole of a variable and the variable has a single chunk.
* Fix chunking error when stride causes whole chunks to be skipped.
* Fix some memory leaks
* Add test cases
* Add one performance test to nczarr_test/. This uses the timer utils from unit_test: timer_utils.[ch].
* Move ncdumpchunks utility from ncdump to nczarr_test

Misc. Other Changes:
* Make check for aws libraries conditional on --enable-nczarr-s3
* Remove all but one bm tests from nczarr_test until they are working.
* Remove another dependency on HDF5 from supposedly non-HDF5 specific code; specifically hdf5_log_hdf5.
* Make the BAIL2 macro be hdf5 specific and replace elsewhere with an HDF5 independent equivalent.
* Move hdf5cache.c to libsrc4/nc4cache.c because it is used by nczarr.
* Modify unit_tests so that some of them are run even if using Windows.
* Misc. small bug fixes and refactors and memory leaks.
* Rename some conflicting tests for cmake.
* Attempted to make nc_perf work with cmake and failed.
2020-12-16 20:48:02 -07:00

196 lines
4.1 KiB
C

/*********************************************************************
* Copyright 2018, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*********************************************************************/
/**
Test the NCxcache data structure
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "netcdf.h"
#include "ncexhash.h"
#include "ncxcache.h"
#include "timer_utils.h"
#ifdef _WIN32
#define srandom srand
#define random (long)rand
#endif
#define DEBUG 0
/* Approximate average times; if we get out of this range, then
something is drastically wrong */
static const struct TimeRange insertrange = {0,50000};
static const struct TimeRange readrange = {0,5000};
static Nanotime inserttime[2];
static Nanotime readtime[2];
#define CHECK(expr) check((expr),__LINE__)
void check(int stat, int line)
{
if(stat) {
fprintf(stderr,"%d: (%d)%s\n",line,stat,nc_strerror(stat));
fflush(stderr);
exit(1);
}
}
/*
Test set 1:
- insert string with obj
- lookup by various methods
- remove
- verify remove
*/
#define MAXSTRLEN 25
#define DEFAULTSEED 1
typedef struct NC_OBJ {
int sort;
char* name;
size_t id;
} NC_OBJ;
typedef struct NCXSTR {
void* next;
void* prev;
void* ptr;
char* string;
} NCXSTR;
//static int N[] = {10, 100, 1000, 0};
static int N[] = {4,0};
/* Generate random ascii strings */
static NCXSTR* strings = NULL;
static void
generatestrings(int n, unsigned seed)
{
int i,k;
long rnd;
int len;
char* s = NULL;
srandom(seed);
strings = (NCXSTR*)calloc(sizeof(NCXSTR),(n+1));
if(strings == NULL) abort();
for(i=0;i<n;i++) {
/* Generate one random string */
if((s = (char*)malloc(1+MAXSTRLEN))==NULL) abort();
rnd = random();
len = rnd % MAXSTRLEN;
/* generate the characters */
for(k=0;k<len;k++) {
do {rnd = random() % 127;} while(rnd < ' ');
assert(rnd > ' ' && rnd < 127);
s[k] = (char)rnd;
}
s[len] = '\0';
strings[i].string = s;
#if DEBUG >= 3
fprintf(stderr,"strings[%d] = |%s|\n",i,strings[i].string);
#endif
}
}
static void
freestrings(void)
{
if(strings) {
NCXSTR* p = strings;
for(;p->string;p++) {nullfree(p->string);}
nullfree(strings);
strings = NULL;
}
}
int
main(int argc, char** argv)
{
int stat = NC_NOERR;
NCxcache* cache = NULL;
ncexhashkey_t hkey;
int* np = NULL;
void* content = NULL;
NCT_inittimer();
for(np=N;*np;np++) {
int ns,i;
ns = *np;
generatestrings(ns,DEFAULTSEED);
fprintf(stderr,"insert:\n");
if((stat = ncxcachenew(2,&cache))) goto done;
NCT_marktime(&inserttime[0]);
for(i=0;i<ns;i++) {
hkey = ncexhashkey((unsigned char*)strings[i].string,strlen(strings[i].string));
if((stat=ncxcacheinsert(cache,hkey,&strings[i]))) goto done;
}
assert(ncxcachecount(cache) == ns);
NCT_marktime(&inserttime[1]);
#if DEBUG > 0
ncxcacheprint(cache);
#endif
NCT_reporttime(ns, inserttime, insertrange, "insert");
/* Try to touch and extract all the entries */
fprintf(stderr,"read:\n");
NCT_marktime(&readtime[0]);
for(i=0;i<ns;i++) {
void* top = NULL;
hkey = ncexhashkey((unsigned char*)strings[i].string,strlen(strings[i].string));
if((stat=ncxcachelookup(cache,hkey,&content))) goto done;
if((stat=ncxcachetouch(cache,hkey))) goto done;
top = ncxcachefirst(cache);
if(top != content) {stat = NC_EINTERNAL; goto done;}
}
NCT_marktime(&readtime[1]);
#if DEBUG > 0
ncxcacheprint(cache);
#endif
NCT_reporttime(ns, readtime, readrange, "read");
for(i=0;i<ns;i++) {
void* top = NULL;
hkey = ncexhashkey((unsigned char*)strings[i].string,strlen(strings[i].string));
if((stat=ncxcachetouch(cache,hkey))) goto done;
top = ncxcachefirst(cache);
if(top != &strings[i])
fprintf(stderr,"touch failure: top=%p strings[%d]=%p\n",top,i,&strings[i]);
}
fprintf(stderr,"touch: passed\n");
freestrings();
ncxcachefree(cache);
}
done:
if(stat) fprintf(stderr,"***fail: %s\n",nc_strerror(stat));
return 0;
}