File: hashset.h

package info (click to toggle)
ruby-ferret 0.11.8.4%2Bdebian-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,368 kB
  • sloc: ansic: 69,786; ruby: 8,131; makefile: 5
file content (215 lines) | stat: -rw-r--r-- 7,852 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#ifndef FRT_HASHSET_H
#define FRT_HASHSET_H

#ifdef __cplusplus
extern "C" {
#endif

#include "hash.h"
#include "global.h"

#define FRT_HS_MIN_SIZE 4
typedef struct FrtHashSetEntry {
    void *elem;
    struct FrtHashSetEntry *next;
    struct FrtHashSetEntry *prev;
} FrtHashSetEntry;

typedef struct FrtHashSet
{
    /* the number of elements in the instance */
    int size;

    /* the first element in the list of elements in the FrtHashSet. The elements
     * will be listed in the order they were added and can be iterated over by
     * following the ->next pointer */
    FrtHashSetEntry *first;

    /* the last element in the list of elements in the FrtHashSet. This is used
     * internally to add elements to the list. */
    FrtHashSetEntry *last;

    /* Hash used internally */
    FrtHash *ht;

    /* Internal: Frees elements added to the FrtHashSet. Should never be NULL */
    frt_free_ft free_elem_i;
} FrtHashSet;

/**
 * Create a new FrtHashSet. The function will allocate a FrtHashSet Struct
 * setting the functions used to hash the objects it will contain and the eq
 * function. This should be used for non-string types.
 *
 * @param hash function to hash objects added to the FrtHashSet
 * @param eq function to determine whether two items are equal
 * @param free_elem function used to free elements as added to the FrtHashSet
 *   when the FrtHashSet if destroyed or duplicate elements are added to the Set
 * @return a newly allocated FrtHashSet structure
 */
extern FrtHashSet *frt_hs_new(frt_hash_ft hash_func,
                                 frt_eq_ft eq_func,
                                 frt_free_ft free_func);

/**
 * Create a new FrtHashSet specifically for strings. This will create a
 * FrtHashSet as if you used frt_hs_new with the standard string hash and eq
 * functions.
 *
 * @param free_elem function used to free elements as added to the FrtHashSet
 *   when the FrtHashSet if destroyed or duplicate elements are added to the Set
 * @return a newly allocated FrtHashSet structure
 */
extern FrtHashSet *frt_hs_new_str(frt_free_ft free_func);

/**
 * Create a new FrtHashSet specifically for pointers. Note that the only way
 * two pointers will be considered equal is if they have the same address. So
 * you can add the string "key" twice if it is stored at two different
 * addresses.
 *
 * @param free_elem function used to free elements as added to the FrtHashSet
 *   when the FrtHashSet if destroyed or duplicate elements are added to the Set
 * @return a newly allocated FrtHashSet structure
 */
extern FrtHashSet *frt_hs_new_ptr(frt_free_ft free_func);

/**
 * Free the memory allocated by the FrtHashSet, but don't free the elements added
 * to the FrtHashSet. If you'd like to free everything in the FrtHashSet you should
 * use frt_hs_destroy
 *
 * @param hs the FrtHashSet to free
 */
extern void frt_hs_free(FrtHashSet *self);

/**
 * Destroy the FrtHashSet including all elements added to the FrtHashSet. If you'd
 * like to free the memory allocated to the FrtHashSet without touching the
 * elements in the FrtHashSet then use frt_hs_free
 *
 * @param hs the FrtHashSet to destroy
 */
extern void frt_hs_destroy(FrtHashSet *self);

/**
 * WARNING: this function may destroy some elements if you add them to a
 * FrtHashSet were equivalent elements already exist, depending on how free_elem
 * was set.
 *
 * Add the element to the FrtHashSet whether or not it was already in the
 * FrtHashSet.
 *
 * When a element is added to the Hash where it already exists, free_elem
 * is called on it, ie the element you tried to add might get destroyed.
 *
 * @param hs the FrtHashSet to add the element to
 * @param elem the element to add to the FrtHashSet
 * @return one of three values;
 *   <pre>
 *     HASH_KEY_DOES_NOT_EXIST  the element was not already in the FrtHashSet.
 *                              This value is equal to 0 or false
 *     HASH_KEY_SAME            the element was identical (same memory
 *                              pointer) to an existing element so no freeing
 *                              was done
 *     HASH_KEY_EQUAL           the element was equal to an element already in
 *                              the FrtHashSet so the new_elem was freed if
 *                              free_elem was set
 *   </pre>
 */
extern FrtHashKeyStatus frt_hs_add(FrtHashSet *self, void *elem);

/**
 * Add element to the FrtHashSet. If the element already existed in the FrtHashSet
 * and the new element was equal but not the same (same pointer/memory) then
 * don't add the element and return false, otherwise return true.
 *
 * @param hs the FrtHashSet to add the element to
 * @param elem the element to add to the FrtHashSet
 * @return true if the element was successfully added or false otherwise
 */
extern int frt_hs_add_safe(FrtHashSet *self, void *elem);

/**
 * Delete the element from the FrtHashSet. Returns true if the item was
 * successfully deleted or false if the element never existed.
 *
 * @param hs the FrtHashSet to delete from
 * @param elem the element to delete
 * @return true if the element was deleted or false if the element never
 *   existed
 */
extern int frt_hs_del(FrtHashSet *self, const void *elem);

/**
 * Remove an item from the FrtHashSet without actually freeing the item. This
 * function should return the item itself so that it can be freed later if
 * necessary.
 *
 * @param hs the FrtHashSet to remove the element from.
 * @param elem the element to remove
 * @param the element that was removed or NULL otherwise
 */
extern void *frt_hs_rem(FrtHashSet *self, const void *elem);

/**
 * Check if the element exists and return the appropriate value described
 * bellow.
 *
 * @param hs the FrtHashSet to check in
 * @param elem the element to check for
 * @return one of the following values
 * <pre>
 *     HASH_KEY_DOES_NOT_EXIST  the element was not already in the FrtHashSet.
 *                              This value is equal to 0 or false
 *     HASH_KEY_SAME            the element was identical (same memory
 *                              pointer) to an existing element so no freeing
 *                              was done
 *     HASH_KEY_EQUAL           the element was equal to an element already in
 *                              the FrtHashSet so the new_elem was freed if
 *                              free_elem was set
 *   </pre>
 */
extern FrtHashKeyStatus frt_hs_exists(FrtHashSet *self, const void *elem);

/**
 * Merge two HashSets. When a merge is done the merger (self) Hash is
 * returned and the mergee is destroyed. All elements from mergee that were
 * not found in merger (self) will be added to self, otherwise they will be
 * destroyed.
 *
 * @param self the FrtHashSet to merge into
 * @param other HastSet to be merged into self
 * @return the merged FrtHashSet
 */
extern FrtHashSet *frt_hs_merge(FrtHashSet *self, FrtHashSet *other);

/**
 * Return the original version of +elem+. So if you allocate two elements
 * which are equal and add the first to the FrtHashSet, calling this function
 * with the second element will return the first element from the FrtHashSet.
 */
extern void *frt_hs_orig(FrtHashSet *self, const void *elem);

/**
 * Clear all elements from the FrtHashSet. If free_elem was set then use it to
 * free all elements as they are cleared. After the method is called, the
 * HashSets size will be 0.
 *
 * @param self the FrtHashSet to clear
 */
extern void frt_hs_clear(FrtHashSet *self);

/* TODO: finish implementing these functions FrtHashSet
int hs_osf(FrtHashSet *hs, void *elem);
FrtHashSet hs_or(FrtHashSet *hs1, FrtHashSet *h2);
FrtHashSet hs_excl_or(FrtHashSet *hs1, FrtHashSet *h2);
FrtHashSet hs_and(FrtHashSet *hs1, FrtHashSet *h2);
FrtHashSet hs_mask(FrtHashSet *hs1, FrtHashSet *h2);
*/

#ifdef __cplusplus
} // extern "C"
#endif

#endif