Adding ASTTransform ...
[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 template<typename _Key>
15 struct LinkNode {
16         _Key key;
17         LinkNode<_Key> *prev;
18         LinkNode<_Key> *next;
19 };
20
21 template<typename _Key, typename _KeyInt, int _Shift, unsigned int (*hash_function)(_Key), bool (*equals)(_Key, _Key)>
22 class HashSet;
23
24 template<typename _Key, typename _KeyInt, int _Shift, unsigned int (*hash_function)(_Key) = default_hash_function<_Key, _Shift, _KeyInt>, bool (*equals)(_Key, _Key) = default_equals<_Key> >
25 class HSIterator {
26 public:
27         HSIterator(LinkNode<_Key> *_curr, HashSet <_Key, _KeyInt, _Shift, hash_function, equals> * _set) :
28                 curr(_curr),
29                 set(_set)
30         {
31         }
32
33         /** Override: new operator */
34         void * operator new(size_t size) {
35                 return ourmalloc(size);
36         }
37
38         /** Override: delete operator */
39         void operator delete(void *p, size_t size) {
40                 ourfree(p);
41         }
42
43         /** Override: new[] operator */
44         void * operator new[](size_t size) {
45                 return ourmalloc(size);
46         }
47
48         /** Override: delete[] operator */
49         void operator delete[](void *p, size_t size) {
50                 ourfree(p);
51         }
52
53         bool hasNext() {
54                 return curr!=NULL;
55         }
56
57         _Key next() {
58                 _Key k=curr->key;
59                 last=curr;
60                 curr=curr->next;
61                 return k;
62         }
63
64         _Key currKey() {
65                 return last->key;
66         }
67
68         void remove() {
69                 _Key k=last->key;
70                 set->remove(k);
71         }
72
73 private:
74         LinkNode<_Key> *curr;
75         LinkNode<_Key> *last;
76         HashSet <_Key, _KeyInt, _Shift, hash_function, equals> * set;
77 };
78
79 template<typename _Key, typename _KeyInt, int _Shift = 0, unsigned int (*hash_function)(_Key) = default_hash_function<_Key, _Shift, _KeyInt>, bool (*equals)(_Key, _Key) = default_equals<_Key> >
80 class HashSet {
81 public:
82         HashSet(unsigned int initialcapacity = 16, double factor = 0.5) :
83                 table(new HashTable<_Key, LinkNode<_Key> *, _KeyInt, _Shift, hash_function, equals>(initialcapacity, factor)),
84                 list(NULL),
85                 tail(NULL)
86         {
87         }
88
89         /** @brief Hashset destructor */
90         ~HashSet() {
91                 LinkNode<_Key> *tmp=list;
92                 while(tmp!=NULL) {
93                         LinkNode<_Key> *tmpnext=tmp->next;
94                         ourfree(tmp);
95                         tmp=tmpnext;
96                 }
97                 delete table;
98         }
99
100         HashSet<_Key, _KeyInt, _Shift, hash_function, equals> * copy() {
101                 HashSet<_Key, _KeyInt, _Shift, hash_function, equals> *copy=new HashSet<_Key, _KeyInt, _Shift, hash_function, equals>(table->getCapacity(), table->getLoadFactor());
102                 HSIterator<_Key, _KeyInt, _Shift, hash_function, equals> * it=iterator();
103                 while(it->hasNext())
104                         copy->add(it->next());
105                 delete it;
106                 return copy;
107         }
108
109         void reset() {
110                 LinkNode<_Key> *tmp=list;
111                 while(tmp!=NULL) {
112                         LinkNode<_Key> *tmpnext=tmp->next;
113                         ourfree(tmp);
114                         tmp=tmpnext;
115                 }
116                 list=tail=NULL;
117                 table->reset();
118         }
119
120         /** @brief Adds a new key to the hashset.  Returns false if the key
121          *  is already present. */
122
123         void addAll(HashSet<_Key, _KeyInt, _Shift, hash_function, equals> * table) {
124                 HSIterator<_Key, _KeyInt, _Shift, hash_function, equals> * it=iterator();
125                 while(it->hasNext())
126                         add(it->next());
127                 delete it;
128         }
129
130         /** @brief Adds a new key to the hashset.  Returns false if the key
131          *  is already present. */
132
133         bool add(_Key key) {
134                 LinkNode<_Key> * val=table->get(key);
135                 if (val==NULL) {
136                         LinkNode<_Key> * newnode=(LinkNode<_Key> *)ourmalloc(sizeof(struct LinkNode<_Key>));
137                         newnode->prev=tail;
138                         newnode->next=NULL;
139                         newnode->key=key;
140                         if (tail!=NULL)
141                                 tail->next=newnode;
142                         else
143                                 list=newnode;
144                         tail=newnode;
145                         table->put(key, newnode);
146                         return true;
147                 } else
148                         return false;
149         }
150
151         /** @brief Gets the original key corresponding to this one from the
152          *  hashset.  Returns NULL if not present. */
153
154         _Key get(_Key key) {
155                 LinkNode<_Key> * val=table->get(key);
156                 if (val!=NULL)
157                         return val->key;
158                 else
159                         return NULL;
160         }
161
162         _Key getFirstKey() {
163                 return list->key;
164         }
165
166         bool contains(_Key key) {
167                 return table->get(key)!=NULL;
168         }
169
170         bool remove(_Key key) {
171                 LinkNode<_Key> * oldlinknode;
172                 oldlinknode=table->get(key);
173                 if (oldlinknode==NULL) {
174                         return false;
175                 }
176                 table->remove(key);
177
178                 //remove link node from the list
179                 if (oldlinknode->prev==NULL)
180                         list=oldlinknode->next;
181                 else
182                         oldlinknode->prev->next=oldlinknode->next;
183                 if (oldlinknode->next!=NULL)
184                         oldlinknode->next->prev=oldlinknode->prev;
185                 else
186                         tail=oldlinknode->prev;
187                 ourfree(oldlinknode);
188                 return true;
189         }
190
191         unsigned int getSize() {
192                 return table->getSize();
193         }
194
195         bool isEmpty() {
196                 return getSize()==0;
197         }
198
199         HSIterator<_Key, _KeyInt, _Shift, hash_function, equals> * iterator() {
200                 return new HSIterator<_Key, _KeyInt, _Shift, hash_function, equals>(list, this);
201         }
202
203         /** Override: new operator */
204         void * operator new(size_t size) {
205                 return ourmalloc(size);
206         }
207
208         /** Override: delete operator */
209         void operator delete(void *p, size_t size) {
210                 ourfree(p);
211         }
212
213         /** Override: new[] operator */
214         void * operator new[](size_t size) {
215                 return ourmalloc(size);
216         }
217
218         /** Override: delete[] operator */
219         void operator delete[](void *p, size_t size) {
220                 ourfree(p);
221         }
222 private:
223         HashTable<_Key, LinkNode<_Key>*, _KeyInt, _Shift, hash_function, equals> * table;
224         LinkNode<_Key> *list;
225         LinkNode<_Key> *tail;
226 };
227 #endif