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