mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-15 08:30:11 +08:00
196 lines
4.1 KiB
C
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),((size_t)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 = (int)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((unsigned int)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((unsigned int)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;
|
|
}
|