mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-09 08:11:38 +08:00
8cb1fc4cfe
The first was branch newhash0.dmh. As with newhash0.dmh, these changes should be transparent.
121 lines
4.1 KiB
C
121 lines
4.1 KiB
C
/*********************************************************************
|
|
* Copyright 1993, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
* $Header$
|
|
*********************************************************************/
|
|
#ifndef NCHASHMAP_H
|
|
#define NCHASHMAP_H
|
|
|
|
/*
|
|
|
|
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*|
|
|
2. We do a bad hack here because we know that the incoming key
|
|
might be the object id. In this case, we can
|
|
store it directly instead of a pointer to it.
|
|
3. If the incoming is a string, then we we do not copy it;
|
|
this means we do not free it. This has consequences when renaming
|
|
objects.
|
|
*/
|
|
|
|
typedef struct NC_hentry {
|
|
int flags;
|
|
uintptr_t data;
|
|
unsigned int hashkey; /* Hash id */
|
|
size_t keysize;
|
|
uintptr_t key; /* |key| <= |uintptr_t| =>actual content else ptr to content */
|
|
} 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
|
|
The API here is not complete in that some #1 functions do not have
|
|
a corresponding #2 function, and vice-versa.
|
|
The NC_hashmapkey function can be used to effectively convert a #2 to a #1.
|
|
If both functions cases are present, then the #2 case will be suffixed with 0.
|
|
*/
|
|
|
|
/** 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, void* 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*, void* 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*, void* 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*, void* 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*);
|
|
|
|
/* Hacks to access internal state: Use with care */
|
|
|
|
/* Convert an entry from ACTIVE to DELETED;
|
|
Return 0 if not found.
|
|
*/
|
|
extern int NC_hashmapdeactivate(NC_hashmap*, uintptr_t data);
|
|
|
|
/* Return the hash key for specified key; takes key+size*/
|
|
extern unsigned int NC_hashmapkey(void* key, size_t size);
|
|
|
|
#if 0
|
|
/** Removes the storage for the element of the key; takes hashkey.
|
|
Return 1 if found, 0 otherwise; returns the data in datap if !null
|
|
*/
|
|
extern int NC_hashmapremove0(NC_hashmap*, unsigned int key, uintptr_t* datap);
|
|
|
|
/** Returns the data for the key; takes hashkey
|
|
Return 1 if found, 0 otherwise; returns the data in datap if !null
|
|
*/
|
|
extern int NC_hashmapget0(NC_hashmap*, unsigned int hashkey, uintptr_t* datap);
|
|
#endif
|
|
|
|
#endif /*NCHASHMAP_H*/
|
|
|