mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
99 lines
3.1 KiB
C
99 lines
3.1 KiB
C
/*********************************************************************
|
|
* Copyright 2018, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
* $Header$
|
|
*********************************************************************/
|
|
#ifndef NCHASHMAP_H
|
|
#define NCHASHMAP_H
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#include <stdint.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*/
|
|
|