Delta Chat Core C-API
mrhash.h
1 /*******************************************************************************
2  *
3  * Delta Chat Core
4  * Copyright (C) 2017 Björn Petersen
5  * Contact: r10s@b44t.com, http://b44t.com
6  *
7  * This program is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later
10  * version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see http://www.gnu.org/licenses/ .
19  *
20  ******************************************************************************/
21 
22 
23 #ifndef __MRHASH_H__
24 #define __MRHASH_H__
25 #ifdef __cplusplus
26 extern "C"
27 {
28 #endif
29 
30 
31 /* Forward declarations of structures.
32  */
33 typedef struct mrhashelem_t mrhashelem_t;
34 
35 
36 /* A complete hash table is an instance of the following structure.
37  * The internals of this structure are intended to be opaque -- client
38  * code should not attempt to access or modify the fields of this structure
39  * directly. Change this structure only by using the routines below.
40  * However, many of the "procedures" and "functions" for modifying and
41  * accessing this structure are really macros, so we can't really make
42  * this structure opaque.
43  */
44 typedef struct mrhash_t
45 {
46  char keyClass; /* SJHASH_INT, _POINTER, _STRING, _BINARY */
47  char copyKey; /* True if copy of key made on insert */
48  int count; /* Number of entries in this table */
49  mrhashelem_t* first; /* The first element of the array */
50  int htsize; /* Number of buckets in the hash table */
51  struct _ht
52  { /* the hash table */
53  int count; /* Number of entries with this hash */
54  mrhashelem_t* chain; /* Pointer to first entry with this hash */
55  } *ht;
56 } mrhash_t;
57 
58 
59 /* Each element in the hash table is an instance of the following
60  * structure. All elements are stored on a single doubly-linked list.
61  *
62  * Again, this structure is intended to be opaque, but it can't really
63  * be opaque because it is used by macros.
64  */
65 typedef struct mrhashelem_t
66 {
67  mrhashelem_t *next, *prev; /* Next and previous elements in the table */
68  void* data; /* Data associated with this element */
69  void* pKey; /* Key associated with this element */
70  int nKey; /* Key associated with this element */
71 } mrhashelem_t;
72 
73 
74 /*
75  * There are 4 different modes of operation for a hash table:
76  *
77  * MRHASH_INT nKey is used as the key and pKey is ignored.
78  *
79  * MRHASH_POINTER pKey is used as the key and nKey is ignored.
80  *
81  * MRHASH_STRING pKey points to a string that is nKey bytes long
82  * (including the null-terminator, if any). Case
83  * is ignored in comparisons.
84  *
85  * MRHASH_BINARY pKey points to binary data nKey bytes long.
86  * memcmp() is used to compare keys.
87  *
88  * A copy of the key is made for MRHASH_STRING and MRHASH_BINARY
89  * if the copyKey parameter to mrhash_init() is 1.
90  */
91 #define MRHASH_INT 1
92 #define MRHASH_POINTER 2
93 #define MRHASH_STRING 3
94 #define MRHASH_BINARY 4
95 
96 
97 /*
98  * Access routines. To delete an element, insert a NULL pointer.
99  */
100 void mrhash_init (mrhash_t*, int keytype, int copyKey);
101 void* mrhash_insert (mrhash_t*, const void *pKey, int nKey, void *pData);
102 void* mrhash_find (const mrhash_t*, const void *pKey, int nKey);
103 void mrhash_clear (mrhash_t*);
104 
105 
106 /*
107  * Macros for looping over all elements of a hash table. The idiom is
108  * like this:
109  *
110  * SjHash h;
111  * SjHashElem *p;
112  * ...
113  * for(p=mrhash_first(&h); p; p=mrhash_next(p)){
114  * SomeStructure *pData = mrhash_data(p);
115  * // do something with pData
116  * }
117  */
118 #define mrhash_first(H) ((H)->first)
119 #define mrhash_next(E) ((E)->next)
120 #define mrhash_data(E) ((E)->data)
121 #define mrhash_key(E) ((E)->pKey)
122 #define mrhash_keysize(E) ((E)->nKey)
123 
124 
125 /*
126  * Number of entries in a hash table
127  */
128 #define mrhash_count(H) ((H)->count)
129 
130 
131 #ifdef __cplusplus
132 }; /* /extern "C" */
133 #endif
134 #endif /* __MRHASH_H__ */