/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
5.2.7 by Gustav Hartvigsson
* Switched licence to a more permisive one.
1
/*
2
Copyright (c) 2013-2014 Gustav Hartvigsson
3
4
Permission is hereby granted, free of charge, to any person obtaining a copy
5
of this software and associated documentation files (the "Software"), to deal
6
in the Software without restriction, including without limitation the rights
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
copies of the Software, and to permit persons to whom the Software is
9
furnished to do so, subject to the following conditions:
10
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
13
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
THE SOFTWARE.
21
*/
22
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
23
#include "Map.h"
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
24
#include "LinkedList.h"
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
25
#include <stdlib.h>
26
61 by Gustav Hartvigsson
* Made the code more easy to read.
27
struct
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
28
SMap {
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
29
  size_t len; // Length
103 by Gustav Hartvigsson
* General cleanup/make it pritty.
30
  SDynamicArray * array; /*  This is what holds the buckets. These buckets are
52 by Gustav Hartvigsson
* Reorderd CMakeLists.txt list of files
31
                          * in turn also SDynamicArrays; or in template speak:
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
32
                          * SDynamicArray<SLinkedList<SMapItem*>*>*
52 by Gustav Hartvigsson
* Reorderd CMakeLists.txt list of files
33
                          */
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
34
103 by Gustav Hartvigsson
* General cleanup/make it pritty.
35
  CompFunc is_equal; /*  method to check if items are equal. */
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
36
  HashFunc key_hash_func;
37
  FreeFunc free_key;
38
  FreeFunc free_value;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
39
};
40
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
41
void
42
_s_map_internal_free_map_items_for_each (SMap * self,
43
                                         SMapItem * item,
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
44
                                         sboolean free_data);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
45
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
46
SLinkedList *
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
47
_s_map_internal_find_bucket (SMap * self,
48
                             spointer key);
49
50
SMapItem *
51
_s_map_internal_find_item_in_bucket (SMap * self,
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
52
                                     SLinkedList * bucket,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
53
                                     spointer key);
54
61 by Gustav Hartvigsson
* Made the code more easy to read.
55
SMapItem *
56
s_map_item_new (void * key, void * value) {
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
57
  SMapItem * self = malloc (sizeof (SMapItem));
58
  self->key = key;
59
  self->value = value;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
60
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
61
  return self;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
62
}
63
61 by Gustav Hartvigsson
* Made the code more easy to read.
64
void
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
65
s_map_item_free (SMapItem * self,
66
                 FreeFunc free_key,
67
                 FreeFunc free_value) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
68
  s_dbg_print ("Freeing Item!");
69
  if (free_key) {
70
    free_key (self->key);
71
  }
72
  if (free_value) {
73
    free_value (self->value);
74
  }
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
75
  free (self);
76
}
77
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
78
void
79
_internal_s_map_free_buckets (SLinkedList * self);
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
80
61 by Gustav Hartvigsson
* Made the code more easy to read.
81
SMap *
82
s_map_new (CompFunc comp_func,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
83
           HashFunc key_hash_func,
84
           FreeFunc free_key,
85
           FreeFunc free_value) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
86
  s_dbg_print ("Freeing SMap");
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
87
  SMap * self = malloc (sizeof (SMap));
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
88
  self->len = 0;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
89
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
90
  self->is_equal = comp_func;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
91
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
92
  /* free_* functions need to be checked if they are null and set the pointer
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
93
   * to free or s_base_object_free ()... Have to decide which...?
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
94
   */
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
95
  self->free_key = free_key;
96
  self->free_value = free_value;
97
98
  /* if no func is set we have to use some other metod of
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
99
   */
100
  if (key_hash_func == NULL){
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
101
    self->key_hash_func = s_hash_object;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
102
  } else {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
103
    self->key_hash_func = key_hash_func;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
104
  }
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
105
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
106
  self->array = s_dynamic_array_new (S_MAP_DEFAULT_NUMBER_OF_BUCKETS,
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
107
                                     FREEFUNC(_internal_s_map_free_buckets));
108
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
109
  return self;
110
}
111
61 by Gustav Hartvigsson
* Made the code more easy to read.
112
void
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
113
s_map_free (SMap * self, sboolean free_data) {
114
  s_map_for_each (self,
115
                  FOREACHFUNC(_s_map_internal_free_map_items_for_each),
116
                  &free_data);
117
  s_dynamic_array_free (self->array, TRUE);
22 by Gustav Hartvigsson
* Made code compile
118
  free (self);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
119
}
120
61 by Gustav Hartvigsson
* Made the code more easy to read.
121
void
122
s_map_add (SMap * self, spointer key, spointer value) {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
123
  SDynamicArray * array = self->array;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
124
  SMapItem * item = s_map_item_new (key, value);
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
125
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
126
  /* We have to generate a key to use as an index in the DynamicArray. */
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
127
  HashFunc hash_func = self->key_hash_func;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
128
  hash_t hash = hash_func (key);
129
  /* We need to mod it with the max size of the array. */
130
  hash = hash % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
131
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
132
  if (self->len == 0) {
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
133
    /* Since we know that there are no items in the array we can skip the
134
     * check if the new place is taken. and just and an array to it.
135
     */
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
136
    s_dbg_print ("Adding bucket to bucket array");
137
    SLinkedList * bucket = s_linked_list_new (FREEFUNC(_s_map_internal_free_map_items_for_each));
138
    s_dbg_print ("1) Appending item to linked list");
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
139
    s_dynamic_array_set (array, hash, bucket);
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
140
    s_linked_list_append (bucket, item);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
141
  } else {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
142
    s_dbg_print ("SMap size in more than zero.");
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
143
    /* Figure out if the bucket exists. */
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
144
    SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
145
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
146
    if (bucket == NULL) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
147
      s_dbg_print ("Bucket does not exist");
148
      bucket = s_linked_list_new (FREEFUNC(_s_map_internal_free_map_items_for_each));
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
149
    }
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
150
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
151
    if (_s_map_internal_find_item_in_bucket (self, bucket, key)) {
152
      s_warn_print ("Key already exists in SMap\n");
153
      return;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
154
    }
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
155
    s_dbg_print ("2) Appending item to linked list");
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
156
    s_linked_list_append (bucket, item);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
157
  }
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
158
  self->len++;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
159
}
160
61 by Gustav Hartvigsson
* Made the code more easy to read.
161
spointer
162
s_map_get (SMap * self, spointer key) {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
163
  spointer ret_val = NULL;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
164
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
165
  SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
166
  if (bucket) {
167
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
168
    if (item) {
169
      ret_val = item->value;
170
    }
171
  }
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
172
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
173
  return ret_val;
174
}
175
176
void
177
s_map_remove (SMap * self, spointer key) {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
178
  SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
179
  if (bucket) {
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
180
    s_linked_list_head (bucket);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
181
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
182
    if (item) {
183
      s_map_item_free (item, self->free_key, self->free_value);
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
184
      s_linked_list_remove_current (bucket, FALSE);
185
      self->len--;
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
186
      return;
187
    }
188
  }
189
  s_dbg_print ("Could not find item in SMap.\n");
190
}
191
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
192
void
193
s_map_for_each (SMap * self, ForEachFunc foreach_func, spointer user_data) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
194
  s_dbg_print ("Running For Each on SMap");
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
195
  for (size_t i = 0; i <= s_dynamic_array_last_item (self->array); i++) {
196
    SLinkedList * bucket = s_dynamic_array_get (self->array, i);
197
    if (bucket) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
198
      s_dbg_print ("Found bucket");
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
199
      s_linked_list_head (bucket);
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
200
      s_dbg_print ("No of items in list: %zd.", s_linked_list_len (bucket));
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
201
      do {
202
        SMapItem * item = s_linked_list_get_current (bucket);
203
        foreach_func (self, item, user_data);
204
      } while (s_linked_list_next (bucket));
205
    }
206
  }
207
}
208
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
209
SLinkedList *
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
210
_s_map_internal_find_bucket (SMap * self,
211
                             spointer key) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
212
  s_dbg_print ("Looking for bucket");
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
213
  SLinkedList * ret_val = NULL;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
214
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
215
  HashFunc hash_func = self->key_hash_func;
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
216
  hash_t hash = hash_func (key)  % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
217
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
218
  ret_val = s_dynamic_array_get (self->array, hash);
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
219
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
220
  return ret_val;
221
}
222
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
223
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
224
SMapItem *
225
_s_map_internal_find_item_in_bucket (SMap * self,
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
226
                                     SLinkedList * bucket,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
227
                                     spointer key) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
228
  s_dbg_print ("Looking for item in bucket");
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
229
  s_linked_list_head (bucket);
230
  do {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
231
    SMapItem * item = SMAPITEM (s_linked_list_get_current (bucket));
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
232
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
233
    if (item && self->is_equal (item->key, key)) {
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
234
      s_dbg_print ("Found Item in Bucket.");
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
235
      return item;
236
    }
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
237
  } while (s_linked_list_next (bucket));
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
238
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
239
  return NULL;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
240
}
241
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
242
#if 0
61 by Gustav Hartvigsson
* Made the code more easy to read.
243
void
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
244
_s_map_internal_free_array_for_each (SDynamicArray * obj,
74 by Gustav Hartvigsson
* forgot a few s_dynamic_array_* functions...
245
                                     SLinkedList * item,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
246
                                     SMap * self) {
74 by Gustav Hartvigsson
* forgot a few s_dynamic_array_* functions...
247
  s_linked_list_for_each (item,
248
                          FOREACHFUNC(_s_map_internal_free_bucket_for_each),
249
                          self);
250
  s_linked_list_free (item, FALSE);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
251
}
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
252
#endif
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
253
254
void
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
255
_s_map_internal_free_map_items_for_each (SMap * map,
256
                          SMapItem * item,
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
257
                          sboolean free_data) {
258
  s_dbg_print ("runnnig: _s_map_internal_free_map_items_for_each");
259
  if (free_data) {
260
    s_dbg_print ("Freeing K:V pair");
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
261
    s_map_item_free (item, map->free_key, map->free_value);
262
  } else {
263
    free (item);
264
  }
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
265
}
109.1.1 by Gustav Hartvigsson
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?
266
267
void
268
_internal_s_map_free_buckets (SLinkedList * self) {
269
  s_dbg_print ("Freeing bucket.");
270
  s_linked_list_free (self, TRUE);
271
}