netcdf-c/include/ncexhash.h
Dennis Heimbigner 90fd1406bc Make use of clock_gettime be conditional.
Re: GH Issue https://github.com/Unidata/netcdf-c/issues/1900

Apparently the clock_gettime() function is not always available.
It is used in unit_test/tst_exhash.c and unit_test/tst_xcache.c.

To solve this, a number of things were changed:
* Move the timing code to a new file unit_tests/timer_utils.[ch]
* Modify the timing code to choose one of several timing methods
depending on availability. The prioritized order is as follows:
    1. If Windows, use the QueryPerformanceCounter mechanism else
    2. Use clock_gettime if available else
    3. Use gettimeofday if available else
    4. Use getrusage if available

Note that the resolution of 3 and 4 is less than 1 or 2.

Misc. Other Changes:
* Move the test in CMakeLists.txt that disables unit tests for WIN32 to unit_test/CMakeLists.txt since some unit tests actually work under Visual Studio.
* Fix some of the unit tests to work under visual studio
* Fix problem with using remove() in zmap_nzf.c
* Remove some warning about use of EXTERNL
2020-12-06 18:19:53 -07:00

116 lines
3.5 KiB
C

/*
Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
See LICENSE.txt for license information.
*/
#ifndef NCEXHASH_H
#define NCEXHASH_H
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include "netcdf.h"
/*
Implement extendible hashing as defined in:
````
R. Fagin, J. Nievergelt, N. Pippenger, and H. Strong, "Extendible Hashing -·a fast access method for dynamic files", ACM Transactions on Database Systems, vol. 4, No. 3, pp. 315-344, 1979.
````
*/
/*! Hashmap-related structs.
NOTES:
1. 'data' is the an arbitrary uintptr_t integer or void* pointer.
2. hashkey is a crc64 hash of key -- it is assumed to be unique for keys.
WARNINGS:
1. It is critical that |uintptr_t| == |void*|
*/
#define ncexhashkey_t unsigned long long
#define NCEXHASHKEYBITS 64
typedef struct NCexentry {
ncexhashkey_t hashkey; /* Hash id */
uintptr_t data;
} NCexentry;
typedef struct NCexleaf {
int uid; /* primarily for debug */
struct NCexleaf* next; /* linked list of all leaves for cleanup */
int depth; /* local depth */
int active; /* index of the first emptry slot */
NCexentry* entries; /* |entries| == leaflen*/
} NCexleaf;
/* Top Level Vector */
typedef struct NCexhashmap {
int leaflen; /* # entries a leaf can store */
int depth; /* Global depth */
NCexleaf* leaves; /* head of the linked list of leaves */
int nactive; /* # of active entries in whole table */
NCexleaf** directory; /* |directory| == 2^depth */
int uid; /* unique id counter */
/* Allow a single iterator over the entries */
struct {
int walking; /* 0=>not in use */
int index; /* index of current entry in leaf */
NCexleaf* leaf; /* leaf we are walking */
} iterator;
} NCexhashmap;
/** Creates a new exhash using LSB */
EXTERNL NCexhashmap* ncexhashnew(int leaflen);
/** Reclaims the exhash structure. */
EXTERNL void ncexhashmapfree(NCexhashmap*);
/** Returns the number of active elements. */
EXTERNL int ncexhashcount(NCexhashmap*);
/* Hash key based API */
/* Lookup by Hash Key */
EXTERNL int ncexhashget(NCexhashmap*, ncexhashkey_t hkey, uintptr_t*);
/* Insert by Hash Key */
EXTERNL int ncexhashput(NCexhashmap*, ncexhashkey_t hkey, uintptr_t data);
/* Remove by Hash Key */
EXTERNL int ncexhashremove(NCexhashmap*, ncexhashkey_t hkey, uintptr_t* datap);
/** Change the data for the specified key; takes hashkey. */
EXTERNL int ncexhashsetdata(NCexhashmap*, ncexhashkey_t hkey, uintptr_t newdata, uintptr_t* olddatap);
/** Get map parameters */
EXTERNL int ncexhashinqmap(NCexhashmap* map, int* leaflenp, int* depthp, int* nactivep, int* uidp, int* walkingp);
/* Return the hash key for specified key; takes key+size*/
EXTERNL ncexhashkey_t ncexhashkey(const unsigned char* key, size_t size);
/* Walk the entries in some order */
/*
@return NC_NOERR if keyp and datap are valid
@return NC_ERANGE if iteration is finished
@return NC_EINVAL for all other errors
*/
EXTERNL int ncexhashiterate(NCexhashmap* map, ncexhashkey_t* keyp, uintptr_t* datap);
/* Debugging */
EXTERNL void ncexhashprint(NCexhashmap*);
EXTERNL void ncexhashprintstats(NCexhashmap*);
EXTERNL void ncexhashprintdir(NCexhashmap*, NCexleaf** dir);
EXTERNL void ncexhashprintleaf(NCexhashmap*, NCexleaf* leaf);
EXTERNL void ncexhashprintentry(NCexhashmap* map, NCexentry* entry);
EXTERNL char* ncexbinstr(ncexhashkey_t hkey, int depth);
/* Macro defined functions */
/** Get map parameters */
#define ncexhashmaplength(map) ((map)==NULL?0:(map)->nactive)
#endif /*NCEXHASH_H*/