2020-11-20 08:01:04 +08:00
/*
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>
2020-12-07 09:19:53 +08:00
# include "netcdf.h"
2020-11-20 08:01:04 +08:00
/*
Implement extendible hashing as defined in :
` ` ` `
2021-07-29 00:49:49 +08:00
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.
2020-11-20 08:01:04 +08:00
` ` ` `
*/
/*! 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*/