netcdf-c/include/nchashmap.h
Dennis Heimbigner 25f062528b This completes (for now) the refactoring of libsrc4.
The file docs/indexing.dox tries to provide design
information for the refactoring.

The primary change is to replace all walking of linked
lists with the use of the NCindex data structure.
Ncindex is a combination of a hash table (for name-based
lookup) and a vector (for walking the elements in the index).
Additionally, global vectors are added to NC_HDF5_FILE_INFO_T
to support direct mapping of an e.g. dimid to the NC_DIM_INFO_T
object. These global vectors exist for dimensions, types, and groups
because they have globally unique id numbers.

WARNING:
1. since libsrc4 and libsrchdf4 share code, there are also
   changes in libsrchdf4.
2. Any outstanding pull requests that change libsrc4 or libhdf4
   are likely to cause conflicts with this code.
3. The original reason for doing this was for performance improvements,
   but as noted elsewhere, this may not be significant because
   the meta-data read performance apparently is being dominated
   by the hdf5 library because we do bulk meta-data reading rather
   than lazy reading.
2018-03-16 11:46:18 -06:00

94 lines
3.0 KiB
C

/*********************************************************************
* Copyright 1993, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Header$
*********************************************************************/
#ifndef NCHASHMAP_H
#define NCHASHMAP_H
/*
This hashmap is optimized to assume null-terminated strings as the
key.
Data is presumed to be an index into some other table Assume it
can be compared using simple == The key is some hash of some
null terminated string.
One problem here is that we need to do a final equality check on
the name string to avoid an accidental hash collision. It would
be nice if we had a large enough hashkey that was known to have
an extremely low probability of collisions so we could compare
the hashkeys to determine exact match. A quick internet search
indicates that this is rather more tricky than just using
e.g. crc64 or such. Needs some thought.
*/
/*! Hashmap-related structs.
NOTES:
1. 'data' is the an arbitrary uintptr_t integer or void* pointer.
2. hashkey is a crc32 hash of key
WARNINGS:
1. It is critical that |uintptr_t| == |void*|
*/
typedef struct NC_hentry {
int flags;
uintptr_t data;
unsigned int hashkey; /* Hash id */
size_t keysize;
char* key; /* copy of the key string; kept as unsigned char */
} NC_hentry;
/*
The hashmap object must give us the hash table (table),
the |table| size, and the # of defined entries in the table
*/
typedef struct NC_hashmap {
size_t alloc; /* allocated # of entries */
size_t active; /* # of active entries */
NC_hentry* table;
} NC_hashmap;
/* defined in nchashmap.c */
/*
There are two "kinds" of functions:
1. those that take the key+size -- they compute the hashkey internally.
2. those that take the hashkey directly
*/
/** Creates a new hashmap near the given size. */
extern NC_hashmap* NC_hashmapnew(size_t startsize);
/** Inserts a new element into the hashmap; takes key+size */
/* key points to size bytes to convert to hash key */
extern int NC_hashmapadd(NC_hashmap*, uintptr_t data, const char* key, size_t keysize);
/** Removes the storage for the element of the key; takes key+size.
Return 1 if found, 0 otherwise; returns the data in datap if !null
*/
extern int NC_hashmapremove(NC_hashmap*, const char* key, size_t keysize, uintptr_t* datap);
/** Returns the data for the key; takes key+size.
Return 1 if found, 0 otherwise; returns the data in datap if !null
*/
extern int NC_hashmapget(NC_hashmap*, const char* key, size_t keysize, uintptr_t* datap);
/** Change the data for the specified key; takes hashkey.
Return 1 if found, 0 otherwise
*/
extern int NC_hashmapsetdata(NC_hashmap*, const char* key, size_t keylen, uintptr_t newdata);
/** Returns the number of saved elements. */
extern size_t NC_hashmapcount(NC_hashmap*);
/** Reclaims the hashmap structure. */
extern int NC_hashmapfree(NC_hashmap*);
/* Return the hash key for specified key; takes key+size*/
extern unsigned int NC_hashmapkey(const char* key, size_t size);
#endif /*NCHASHMAP_H*/