/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
                          */
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
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,
80 by Gustav Hartvigsson
* is that better?
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;
52 by Gustav Hartvigsson
* Reorderd CMakeLists.txt list of files
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) {
68
  free_key (self->key);
69
  free_value (self->value);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
70
  free (self);
71
}
72
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
73
74
61 by Gustav Hartvigsson
* Made the code more easy to read.
75
SMap *
76
s_map_new (CompFunc comp_func,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
77
           HashFunc key_hash_func,
78
           FreeFunc free_key,
79
           FreeFunc free_value) {
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
80
  SMap * self = malloc (sizeof (SMap));
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
81
  self->len = 0;
82
  
83
  self->is_equal = comp_func;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
84
  
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
85
  /* free_* functions need to be checked if they are null and set the pointer
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
86
   * to free or s_base_object_free ()... Have to decide which...?
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
87
   */
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
88
  if (free_key) {
89
    self->free_key = free_key;
90
  } else {
91
    self->free_key = FREEFUNC(free);
92
  }
93
  if (free_value) {
94
    self->free_value = free_value;
95
  } else {
96
    self->free_value = FREEFUNC(free);
97
  }
98
  
44 by Gustav Hartvigsson
* Started to structuce the dectumentation a little better.
99
  
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
100
  /* if no func is set we have to use some other metod of 
101
   */
102
  if (key_hash_func == NULL){
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
103
    self->key_hash_func = s_hash_object;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
104
  } else {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
105
    self->key_hash_func = key_hash_func;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
106
  }
107
  
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
108
  self->array = s_dynamic_array_new (S_MAP_DEFAULT_NUMBER_OF_BUCKETS,
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
109
                                     FREEFUNC(s_linked_list_free));
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
110
  
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
111
  return self;
112
}
113
61 by Gustav Hartvigsson
* Made the code more easy to read.
114
void
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
115
s_map_free (SMap * self, sboolean free_data) {
116
  s_map_for_each (self,
117
                  FOREACHFUNC(_s_map_internal_free_map_items_for_each),
118
                  &free_data);
119
  s_dynamic_array_free (self->array, TRUE);
22 by Gustav Hartvigsson
* Made code compile
120
  free (self);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
121
}
122
61 by Gustav Hartvigsson
* Made the code more easy to read.
123
void
124
s_map_add (SMap * self, spointer key, spointer value) {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
125
  SDynamicArray * array = self->array;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
126
  SMapItem * item = s_map_item_new (key, value);
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
127
  
128
  /* We have to generate a key to use as an index in the DynamicArray. */
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
129
  HashFunc hash_func = self->key_hash_func;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
130
  hash_t hash = hash_func (key);
131
  /* We need to mod it with the max size of the array. */
132
  hash = hash % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
133
  
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
134
  if (self->len == 0) {
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
135
    /* Since we know that there are no items in the array we can skip the
136
     * check if the new place is taken. and just and an array to it.
137
     */
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
138
    SLinkedList * bucket = s_linked_list_new (NULL);
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);
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
141
    
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
142
  } else {
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);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
145
    
146
    if (bucket == NULL) {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
147
      bucket = s_linked_list_new (NULL);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
148
    }
149
    
150
    if (_s_map_internal_find_item_in_bucket (self, bucket, key)) {
151
      s_warn_print ("Key already exists in SMap\n");
152
      return;
53 by Gustav Hartvigsson
* Finnished up s_map_add () ???
153
    }
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
154
    s_linked_list_append (bucket, item);
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
155
  }
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
156
  self->len++;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
157
}
158
61 by Gustav Hartvigsson
* Made the code more easy to read.
159
spointer
160
s_map_get (SMap * self, spointer key) {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
161
  spointer ret_val = NULL;
162
  
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
163
  SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
164
  if (bucket) {
165
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
166
    if (item) {
167
      ret_val = item->value;
168
    }
169
  }
170
  
171
  return ret_val;
172
}
173
174
void
175
s_map_remove (SMap * self, spointer key) {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
176
  SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
177
  if (bucket) {
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
178
    s_linked_list_head (bucket);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
179
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
180
    if (item) {
181
      s_map_item_free (item, self->free_key, self->free_value);
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
182
      s_linked_list_remove_current (bucket, FALSE);
183
      self->len--;
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
184
      return;
185
    }
186
  }
187
  s_dbg_print ("Could not find item in SMap.\n");
188
}
189
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
190
void
191
s_map_for_each (SMap * self, ForEachFunc foreach_func, spointer user_data) {
192
  for (size_t i = 0; i <= s_dynamic_array_last_item (self->array); i++) {
193
    SLinkedList * bucket = s_dynamic_array_get (self->array, i);
194
    if (bucket) {
195
      s_linked_list_head (bucket);
196
      do {
197
        SMapItem * item = s_linked_list_get_current (bucket);
198
        foreach_func (self, item, user_data);
199
      } while (s_linked_list_next (bucket));
200
    }
201
  }
202
}
203
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
204
SLinkedList *
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
205
_s_map_internal_find_bucket (SMap * self,
206
                             spointer key) {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
207
  SLinkedList * ret_val = NULL;
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
208
  
209
  HashFunc hash_func = self->key_hash_func;
210
  hash_t hash = hash_func (key);
211
  
212
  ret_val = s_dynamic_array_get (self->array, hash);
213
  
214
  return ret_val;
215
}
216
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
217
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
218
SMapItem *
219
_s_map_internal_find_item_in_bucket (SMap * self,
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
220
                                     SLinkedList * bucket,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
221
                                     spointer key) {
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
222
  s_linked_list_head (bucket);
223
  do {
72 by Gustav Hartvigsson
* Added our own types for stability and shit and giggles.
224
    SMapItem * item = SMAPITEM (s_linked_list_get_current (bucket));
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
225
    if (item && self->is_equal (item->key, key)) {
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
226
      return item;
227
    }
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
228
  } while (s_linked_list_next (bucket));
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
229
  
14 by Gustav Hartvigsson
* Think I am 70% done with SMap now...
230
  return NULL;
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
231
}
232
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
233
#if 0
61 by Gustav Hartvigsson
* Made the code more easy to read.
234
void
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
235
_s_map_internal_free_array_for_each (SDynamicArray * obj,
74 by Gustav Hartvigsson
* forgot a few s_dynamic_array_* functions...
236
                                     SLinkedList * item,
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
237
                                     SMap * self) {
74 by Gustav Hartvigsson
* forgot a few s_dynamic_array_* functions...
238
  s_linked_list_for_each (item,
239
                          FOREACHFUNC(_s_map_internal_free_bucket_for_each),
240
                          self);
241
  s_linked_list_free (item, FALSE);
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
242
}
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
243
#endif
69 by Gustav Hartvigsson
* Finished of SMap... Sort of...
244
245
void
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
246
_s_map_internal_free_map_items_for_each (SMap * map,
247
                          SMapItem * item,
80 by Gustav Hartvigsson
* is that better?
248
                          sboolean * free_data) {
249
  if ((*free_data)) {
79 by Gustav Hartvigsson
* Clean up of SMap's for each code.
250
    s_map_item_free (item, map->free_key, map->free_value);
251
  } else {
252
    free (item);
253
  }
5.2.1 by Gustav Hartvigsson
Started work on the Map (SMap) data structure.
254
}