mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
25f062528b
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.
94 lines
3.0 KiB
C
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*/
|
|
|