More code towards graph
[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 HASHSET_H
11 #define HASHSET_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) = defaultHashFunction<_Key, _Shift, _KeyInt>, bool (*equals)(_Key, _Key) = defaultEquals<_Key> >
25 class SetIterator {
26 public:
27         SetIterator(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) = defaultHashFunction<_Key, _Shift, _KeyInt>, bool (*equals)(_Key, _Key) = defaultEquals<_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                 SetIterator<_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                 SetIterator<_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 Return random key from set. */
152
153         _Key getRandomElement() {
154                 if (getSize() == 0)
155                         return NULL;
156                 else if (getSize() < 6) {
157                         uint count = random() % getSize();
158                         Linknode<_Key> *ptr = list;
159                         while (count > 0) {
160                                 ptr = ptr->next;
161                                 count--;
162                         }
163                         return ptr->key;
164                 } else
165                         return table->getRandomValue()->key;
166         }
167
168         /** @brief Gets the original key corresponding to this one from the
169          *  hashset.  Returns NULL if not present. */
170
171         _Key get(_Key key) {
172                 Linknode<_Key> *val = table->get(key);
173                 if (val != NULL)
174                         return val->key;
175                 else
176                         return NULL;
177         }
178
179         _Key getFirstKey() {
180                 return list->key;
181         }
182
183         bool contains(_Key key) {
184                 return table->get(key) != NULL;
185         }
186
187         bool remove(_Key key) {
188                 Linknode<_Key> *oldlinknode;
189                 oldlinknode = table->get(key);
190                 if (oldlinknode == NULL) {
191                         return false;
192                 }
193                 table->remove(key);
194
195                 //remove link node from the list
196                 if (oldlinknode->prev == NULL)
197                         list = oldlinknode->next;
198                 else
199                         oldlinknode->prev->next = oldlinknode->next;
200                 if (oldlinknode->next != NULL)
201                         oldlinknode->next->prev = oldlinknode->prev;
202                 else
203                         tail = oldlinknode->prev;
204                 ourfree(oldlinknode);
205                 return true;
206         }
207
208         unsigned int getSize() {
209                 return table->getSize();
210         }
211
212         bool isEmpty() {
213                 return getSize() == 0;
214         }
215
216         SetIterator<_Key, _KeyInt, _Shift, hash_function, equals> *iterator() {
217                 return new SetIterator<_Key, _KeyInt, _Shift, hash_function, equals>(list, this);
218         }
219
220         /** Override: new operator */
221         void *operator new(size_t size) {
222                 return ourmalloc(size);
223         }
224
225         /** Override: delete operator */
226         void operator delete(void *p, size_t size) {
227                 ourfree(p);
228         }
229
230         /** Override: new[] operator */
231         void *operator new[](size_t size) {
232                 return ourmalloc(size);
233         }
234
235         /** Override: delete[] operator */
236         void operator delete[](void *p, size_t size) {
237                 ourfree(p);
238         }
239 private:
240         Hashtable<_Key, Linknode<_Key> *, _KeyInt, _Shift, hash_function, equals> *table;
241         Linknode<_Key> *list;
242         Linknode<_Key> *tail;
243 };
244 #endif