mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-03 08:01:25 +08:00
116 lines
3.5 KiB
C
116 lines
3.5 KiB
C
/*
|
|
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>
|
|
#include "netcdf.h"
|
|
|
|
/*
|
|
Implement extendible hashing as defined in:
|
|
````
|
|
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.
|
|
````
|
|
*/
|
|
|
|
/*! 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*/
|
|
|