Reorg code
[satune.git] / src / Collections / hashset.h
1 /*      Copyright (c) 2015 Regents of the University of California
2  *
3  *      Author: Brian Demsky <bdemsky@uci.edu>
4  *
5  *      This program is free software; you can redistribute it and/or
6  *      modify it under the terms of the GNU General Public License
7  *      version 2 as published by the Free Software Foundation.
8  */
9
10 #ifndef HASH_SET_H
11 #define HASH_SET_H
12 #include "hashtable.h"
13
14 #define HashSetDef(Name, _Key, hash_function, equals)                                                                           \
15         struct LinkNode ## Name {                                                                                                                                                                                       \
16                 _Key key;                                                                                                                                                                                                                                               \
17                 struct LinkNode ## Name *prev;                                                                                                                                                  \
18                 struct LinkNode ## Name *next;                                                                                                                                                  \
19         };                                                                                                                                                                                                                                                                              \
20         typedef struct LinkNode ## Name LinkNode ## Name;                                                                                       \
21         struct HashSet ## Name;                                                                                                                                                                                         \
22         typedef struct HashSet ## Name HashSet ## Name;                                                                                         \
23         struct HSIterator ## Name {                                                                                                                                                                             \
24                 LinkNode ## Name *curr;                                                                                                                                                                                 \
25                 LinkNode ## Name *last;                                                                                                                                                                                 \
26                 HashSet ## Name * set;                                                                                                                                                                                  \
27         };                                                                                                                                                                                                                                                                              \
28         typedef struct HSIterator ## Name HSIterator ## Name;                                                                   \
29         HashTableDef(Name ## Set, _Key, LinkNode ## Name *, hash_function, equals); \
30         HSIterator ## Name * allocHSIterator ## Name(LinkNode ## Name *_curr, HashSet ## Name * _set); \
31         void deleteIter ## Name(HSIterator ## Name *hsit);                                                                                      \
32         bool hasNext ## Name(HSIterator ## Name *hsit);                                                                                         \
33         _Key next ## Name(HSIterator ## Name *hsit);                                                                                                    \
34         _Key currKey ## Name(HSIterator ## Name *hsit);                                                                                         \
35         void removeIter ## Name(HSIterator ## Name *hsit);                                                                                              \
36         struct HashSet ## Name {                                                                                                                                                                                        \
37                 HashTable ## Name ## Set * table;                                                                                                                                               \
38                 LinkNode ## Name *list;                                                                                                                                                                                 \
39                 LinkNode ## Name *tail;                                                                                                                                                                                 \
40         };                                                                                                                                                                                                                                                                              \
41         typedef struct HashSet ## Name HashSet ## Name;                                                                                         \
42                                                                                                                                                                                                                                                                                                 \
43         HashSet ## Name * allocHashSet ## Name (unsigned int initialcapacity, double factor);   \
44         void deleteHashSet ## Name(struct HashSet ## Name * set);                                                               \
45         HashSet ## Name * copy ## Name(HashSet ## Name * set);                                                          \
46         void resetSet ## Name(HashSet ## Name * set);                                                                                                   \
47         bool add ## Name(HashSet ## Name * set,_Key key);                                                                                       \
48         _Key getSet ## Name(HashSet ## Name * set,_Key key);                                                                    \
49         _Key getFirstKey ## Name(HashSet ## Name * set);                                                                                        \
50         bool containsSet ## Name(HashSet ## Name * set,_Key key);                                                       \
51         bool removeSet ## Name(HashSet ## Name * set,_Key key);                                                         \
52         unsigned int getSizeSet ## Name(HashSet ## Name * set);                                                         \
53         bool isEmpty ## Name(HashSet ## Name * set);                                                                                                    \
54         HSIterator ## Name * iterator ## Name(HashSet ## Name * set);
55
56
57 #define HashSetImpl(Name, _Key, hash_function, equals)                                                                  \
58         HashTableImpl(Name ## Set, _Key, LinkNode ## Name *, hash_function, equals); \
59         HSIterator ## Name * allocHSIterator ## Name(LinkNode ## Name *_curr, HashSet ## Name * _set) { \
60                 HSIterator ## Name * hsit = (HSIterator ## Name *) ourmalloc(sizeof(HSIterator ## Name)); \
61                 hsit->curr=_curr;                                                                                                                                                                                                               \
62                 hsit->set=_set;                                                                                                                                                                                                                 \
63                 return hsit;                                                                                                                                                                                                                            \
64         }                                                                                                                                                                                                                                                                                       \
65                                                                                                                                                                                                                                                                                                 \
66         void deleteIter ## Name(HSIterator ## Name *hsit) {                                                                             \
67                 ourfree(hsit);                                                                                                                                                                                                                  \
68         }                                                                                                                                                                                                                                                                                       \
69                                                                                                                                                                                                                                                                                                 \
70         bool hasNext ## Name(HSIterator ## Name *hsit) {                                                                                        \
71                 return hsit->curr!=NULL;                                                                                                                                                                                \
72         }                                                                                                                                                                                                                                                                                       \
73                                                                                                                                                                                                                                                                                                 \
74         _Key next ## Name(HSIterator ## Name *hsit) {                                                                                                   \
75                 _Key k=hsit->curr->key;                                                                                                                                                                                 \
76                 hsit->last=hsit->curr;                                                                                                                                                                                  \
77                 hsit->curr=hsit->curr->next;                                                                                                                                                            \
78                 return k;                                                                                                                                                                                                                                               \
79         }                                                                                                                                                                                                                                                                                       \
80                                                                                                                                                                                                                                                                                                 \
81         _Key currKey ## Name(HSIterator ## Name *hsit) {                                                                                        \
82                 return hsit->last->key;                                                                                                                                                                                 \
83         }                                                                                                                                                                                                                                                                                       \
84                                                                                                                                                                                                                                                                                                 \
85         void removeIter ## Name(HSIterator ## Name *hsit) {                                                                             \
86                 _Key k=hsit->last->key;                                                                                                                                                                                 \
87                 removeSet ## Name(hsit->set, k);                                                                                                                                                \
88         }                                                                                                                                                                                                                                                                                       \
89                                                                                                                                                                                                                                                                                                 \
90         HashSet ## Name * allocHashSet ## Name (unsigned int initialcapacity, double factor) { \
91                 HashSet ## Name * set = (HashSet ## Name *) ourmalloc(sizeof(struct HashSet ## Name));  \
92                 set->table=allocHashTable ## Name ## Set(initialcapacity, factor);                                      \
93                 set->list=NULL;                                                                                                                                                                                                                 \
94                 set->tail=NULL;                                                                                                                                                                                                                 \
95                 return set;                                                                                                                                                                                                                                     \
96 }                                                                                                                                                                                                                                                                                               \
97                                                                                                                                                                                                                                                                                                 \
98         void deleteHashSet ## Name(struct HashSet ## Name * set) {                                              \
99                 LinkNode ## Name *tmp=set->list;                                                                                                                                                \
100                 while(tmp!=NULL) {                                                                                                                                                                                                      \
101                         LinkNode ## Name *tmpnext=tmp->next;                                                                                                                    \
102                         ourfree(tmp);                                                                                                                                                                                                                   \
103                         tmp=tmpnext;                                                                                                                                                                                                                    \
104                 }                                                                                                                                                                                                                                                                               \
105                 deleteHashTable ## Name ## Set(set->table);                                                                                                     \
106                 ourfree(set);                                                                                                                                                                                                                           \
107         }                                                                                                                                                                                                                                                                                       \
108                                                                                                                                                                                                                                                                                                 \
109         HashSet ## Name * copy ## Name(HashSet ## Name * set) {                                                         \
110                 HashSet ## Name *copy=allocHashSet ## Name(getCapacity ## Name ## Set(set->table), getLoadFactor ## Name ## Set(set->table)); \
111                 HSIterator ## Name * it=iterator ## Name(set);                                                                                  \
112                 while(hasNext ## Name(it))                                                                                                                                                                      \
113                         add ## Name(copy, next ## Name(it));                                                                                                                    \
114                 deleteIter ## Name(it);                                                                                                                                                                                 \
115                 return copy;                                                                                                                                                                                                                            \
116         }                                                                                                                                                                                                                                                                                       \
117                                                                                                                                                                                                                                                                                                 \
118         void resetSet ## Name(HashSet ## Name * set) {                                                                                          \
119                 LinkNode ## Name *tmp=set->list;                                                                                                                                                \
120                 while(tmp!=NULL) {                                                                                                                                                                                                      \
121                         LinkNode ## Name *tmpnext=tmp->next;                                                                                                                    \
122                         ourfree(tmp);                                                                                                                                                                                                                   \
123                         tmp=tmpnext;                                                                                                                                                                                                                    \
124                 }                                                                                                                                                                                                                                                                               \
125                 set->list=set->tail=NULL;                                                                                                                                                                               \
126                 reset ## Name ## Set(set->table);                                                                                                                                               \
127         }                                                                                                                                                                                                                                                                                       \
128                                                                                                                                                                                                                                                                                                 \
129         bool add ## Name(HashSet ## Name * set,_Key key) {                                                                              \
130                 LinkNode ## Name * val=get ## Name ## Set(set->table, key);                                     \
131                 if (val==NULL) {                                                                                                                                                                                                                \
132                         LinkNode ## Name * newnode=(LinkNode ## Name *)ourmalloc(sizeof(struct LinkNode ## Name)); \
133                         newnode->prev=set->tail;                                                                                                                                                                        \
134                         newnode->next=NULL;                                                                                                                                                                                             \
135                         newnode->key=key;                                                                                                                                                                                                       \
136                         if (set->tail!=NULL)                                                                                                                                                                                    \
137                                 set->tail->next=newnode;                                                                                                                                                                \
138                         else                                                                                                                                                                                                                                                    \
139                                 set->list=newnode;                                                                                                                                                                                      \
140                         set->tail=newnode;                                                                                                                                                                                              \
141                         put ## Name ## Set(set->table, key, newnode);                                                                                   \
142                         return true;                                                                                                                                                                                                                    \
143                 } else                                                                                                                                                                                                                                                  \
144                         return false;                                                                                                                                                                                                                   \
145         }                                                                                                                                                                                                                                                                                       \
146                                                                                                                                                                                                                                                                                                 \
147         _Key getSet ## Name(HashSet ## Name * set,_Key key) {                                                                   \
148                 LinkNode ## Name * val=get ## Name ## Set(set->table, key);                                     \
149                 if (val!=NULL)                                                                                                                                                                                                                  \
150                         return val->key;                                                                                                                                                                                                        \
151                 else                                                                                                                                                                                                                                                            \
152                         return NULL;                                                                                                                                                                                                                    \
153         }                                                                                                                                                                                                                                                                                       \
154                                                                                                                                                                                                                                                                                                 \
155         _Key getFirstKey ## Name(HashSet ## Name * set) {                                                                                       \
156                 return set->list->key;                                                                                                                                                                                  \
157         }                                                                                                                                                                                                                                                                                       \
158                                                                                                                                                                                                                                                                                                 \
159         bool containsSet ## Name(HashSet ## Name * set,_Key key) {                                              \
160                 return get ## Name ## Set(set->table, key)!=NULL;                                                                               \
161         }                                                                                                                                                                                                                                                                                       \
162                                                                                                                                                                                                                                                                                                 \
163         bool removeSet ## Name(HashSet ## Name * set,_Key key) {                                                        \
164                 LinkNode ## Name * oldlinknode;                                                                                                                                                 \
165                 oldlinknode=get ## Name ## Set(set->table, key);                                                                                \
166                 if (oldlinknode==NULL) {                                                                                                                                                                                \
167                         return false;                                                                                                                                                                                                                   \
168                 }                                                                                                                                                                                                                                                                               \
169                 remove ## Name ## Set(set->table, key);                                                                                                                 \
170                                                                                                                                                                                                                                                                                                 \
171                 if (oldlinknode->prev==NULL)                                                                                                                                                            \
172                         set->list=oldlinknode->next;                                                                                                                                                    \
173                 else                                                                                                                                                                                                                                                            \
174                         oldlinknode->prev->next=oldlinknode->next;                                                                                              \
175                 if (oldlinknode->next!=NULL)                                                                                                                                                            \
176                         oldlinknode->next->prev=oldlinknode->prev;                                                                                              \
177                 else                                                                                                                                                                                                                                                            \
178                         set->tail=oldlinknode->prev;                                                                                                                                                    \
179                 ourfree(oldlinknode);                                                                                                                                                                                           \
180                 return true;                                                                                                                                                                                                                            \
181         }                                                                                                                                                                                                                                                                                       \
182                                                                                                                                                                                                                                                                                                 \
183         unsigned int getSizeSet ## Name(HashSet ## Name * set) {                                                        \
184                 return getSizeTable ## Name ## Set(set->table);                                                                                 \
185         }                                                                                                                                                                                                                                                                                       \
186                                                                                                                                                                                                                                                                                                 \
187         bool isEmpty ## Name(HashSet ## Name * set) {                                                                                                   \
188                 return getSizeSet ## Name(set)==0;                                                                                                                                      \
189         }                                                                                                                                                                                                                                                                                       \
190                                                                                                                                                                                                                                                                                                 \
191         HSIterator ## Name * iterator ## Name(HashSet ## Name * set) {                          \
192                 return allocHSIterator ## Name(set->list, set);                                                                                 \
193         }       
194 #endif