]> arthur.barton.de Git - netatalk.git/blob - include/atalk/hash.h
Writing metadata xattr on directories with sticky bit set, FR#94
[netatalk.git] / include / atalk / hash.h
1 /*
2  * Hash Table Data Type
3  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
4  *
5  * Free Software License:
6  *
7  * All rights are reserved by the author, with the following exceptions:
8  * Permission is granted to freely reproduce and distribute this software,
9  * possibly in exchange for a fee, provided that this copyright notice appears
10  * intact. Permission is also granted to adapt this software to produce
11  * derivative works, as long as the modified versions carry this copyright
12  * notice and additional notices stating that the work has been modified.
13  * This source code may be translated into executable form and incorporated
14  * into proprietary software; there is no requirement for such software to
15  * contain a copyright notice related to this source.
16  *
17  * $Name:  $
18  */
19
20 #ifndef ATALK_HASH_H
21 #define ATALK_HASH_H
22
23 #include <limits.h>
24 #include <stdint.h>
25
26 typedef unsigned long hashcount_t;
27 #define HASHCOUNT_T_MAX ULONG_MAX
28
29 typedef uint32_t hash_val_t;
30 #define HASH_VAL_T_MAX UINT32_MAX
31
32 extern int hash_val_t_bit;
33
34 #ifndef HASH_VAL_T_BIT
35 #define HASH_VAL_T_BIT ((int) hash_val_t_bit)
36 #endif
37
38 /*
39  * Hash chain node structure.
40  * Notes:
41  * 1. This preprocessing directive is for debugging purposes.  The effect is
42  *    that if the preprocessor symbol KAZLIB_OPAQUE_DEBUG is defined prior to the
43  *    inclusion of this header,  then the structure shall be declared as having
44  *    the single member   int __OPAQUE__.   This way, any attempts by the
45  *    client code to violate the principles of information hiding (by accessing
46  *    the structure directly) can be diagnosed at translation time. However,
47  *    note the resulting compiled unit is not suitable for linking.
48  * 2. This is a pointer to the next node in the chain. In the last node of a
49  *    chain, this pointer is null.
50  * 3. The key is a pointer to some user supplied data that contains a unique
51  *    identifier for each hash node in a given table. The interpretation of
52  *    the data is up to the user. When creating or initializing a hash table,
53  *    the user must supply a pointer to a function for comparing two keys,
54  *    and a pointer to a function for hashing a key into a numeric value.
55  * 4. The value is a user-supplied pointer to void which may refer to
56  *    any data object. It is not interpreted in any way by the hashing
57  *    module.
58  * 5. The hashed key is stored in each node so that we don't have to rehash
59  *    each key when the table must grow or shrink.
60  */
61
62 typedef struct hnode_t {
63     #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)   /* 1 */
64     struct hnode_t *hash_next;          /* 2 */
65     const void *hash_key;               /* 3 */
66     void *hash_data;                    /* 4 */
67     hash_val_t hash_hkey;               /* 5 */
68     #else
69     int hash_dummy;
70     #endif
71 } hnode_t;
72
73 /*
74  * The comparison function pointer type. A comparison function takes two keys
75  * and produces a value of -1 if the left key is less than the right key, a
76  * value of 0 if the keys are equal, and a value of 1 if the left key is
77  * greater than the right key.
78  */
79
80 typedef int (*hash_comp_t)(const void *, const void *);
81
82 /*
83  * The hashing function performs some computation on a key and produces an
84  * integral value of type hash_val_t based on that key. For best results, the
85  * function should have a good randomness properties in *all* significant bits
86  * over the set of keys that are being inserted into a given hash table. In
87  * particular, the most significant bits of hash_val_t are most significant to
88  * the hash module. Only as the hash table expands are less significant bits
89  * examined. Thus a function that has good distribution in its upper bits but
90  * not lower is preferrable to one that has poor distribution in the upper bits
91  * but not the lower ones.
92  */
93
94 typedef hash_val_t (*hash_fun_t)(const void *);
95
96 /*
97  * allocator functions
98  */
99
100 typedef hnode_t *(*hnode_alloc_t)(void *);
101 typedef void (*hnode_free_t)(hnode_t *, void *);
102
103 /*
104  * This is the hash table control structure. It keeps track of information
105  * about a hash table, as well as the hash table itself.
106  * Notes:
107  * 1.  Pointer to the hash table proper. The table is an array of pointers to
108  *     hash nodes (of type hnode_t). If the table is empty, every element of
109  *     this table is a null pointer. A non-null entry points to the first
110  *     element of a chain of nodes.
111  * 2.  This member keeps track of the size of the hash table---that is, the
112  *     number of chain pointers.
113  * 3.  The count member maintains the number of elements that are presently
114  *     in the hash table.
115  * 4.  The maximum count is the greatest number of nodes that can populate this
116  *     table. If the table contains this many nodes, no more can be inserted,
117  *     and the hash_isfull() function returns true.
118  * 5.  The high mark is a population threshold, measured as a number of nodes,
119  *     which, if exceeded, will trigger a table expansion. Only dynamic hash
120  *     tables are subject to this expansion.
121  * 6.  The low mark is a minimum population threshold, measured as a number of
122  *     nodes. If the table population drops below this value, a table shrinkage
123  *     will occur. Only dynamic tables are subject to this reduction.  No table
124  *     will shrink beneath a certain absolute minimum number of nodes.
125  * 7.  This is the a pointer to the hash table's comparison function. The
126  *     function is set once at initialization or creation time.
127  * 8.  Pointer to the table's hashing function, set once at creation or
128  *     initialization time.
129  * 9.  The current hash table mask. If the size of the hash table is 2^N,
130  *     this value has its low N bits set to 1, and the others clear. It is used
131  *     to select bits from the result of the hashing function to compute an
132  *     index into the table.
133  * 10. A flag which indicates whether the table is to be dynamically resized. It
134  *     is set to 1 in dynamically allocated tables, 0 in tables that are
135  *     statically allocated.
136  */
137
138 typedef struct hash_t {
139     #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
140     struct hnode_t **hash_table;                /* 1 */
141     hashcount_t hash_nchains;                   /* 2 */
142     hashcount_t hash_nodecount;                 /* 3 */
143     hashcount_t hash_maxcount;                  /* 4 */
144     hashcount_t hash_highmark;                  /* 5 */
145     hashcount_t hash_lowmark;                   /* 6 */
146     hash_comp_t hash_compare;                   /* 7 */
147     hash_fun_t hash_function;                   /* 8 */
148     hnode_alloc_t hash_allocnode;
149     hnode_free_t hash_freenode;
150     void *hash_context;
151     hash_val_t hash_mask;                       /* 9 */
152     int hash_dynamic;                           /* 10 */
153     #else
154     int hash_dummy;
155     #endif
156 } hash_t;
157
158 /*
159  * Hash scanner structure, used for traversals of the data structure.
160  * Notes:
161  * 1. Pointer to the hash table that is being traversed.
162  * 2. Reference to the current chain in the table being traversed (the chain
163  *    that contains the next node that shall be retrieved).
164  * 3. Pointer to the node that will be retrieved by the subsequent call to
165  *    hash_scan_next().
166  */
167
168 typedef struct hscan_t {
169     #if defined(HASH_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
170     hash_t *hash_table;         /* 1 */
171     hash_val_t hash_chain;      /* 2 */
172     hnode_t *hash_next;         /* 3 */
173     #else
174     int hash_dummy;
175     #endif
176 } hscan_t;
177
178
179 #endif /* ATALK_HASH_H */