/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk

« back to all changes in this revision

Viewing changes to libssts/Map.c

  • Committer: Gustav Hartvigsson
  • Date: 2015-10-28 14:45:22 UTC
  • mto: This revision was merged to the branch mainline in revision 111.
  • Revision ID: gustav.hartvigsson@gmail.com-20151028144522-fo54z73ssjex0emw
* SMap seems to be broken... Or could it be SObject's Callback stuff? Or SLinkedList?

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
                          * in turn also SDynamicArrays; or in template speak:
32
32
                          * SDynamicArray<SLinkedList<SMapItem*>*>*
33
33
                          */
34
 
  
 
34
 
35
35
  CompFunc is_equal; /*  method to check if items are equal. */
36
36
  HashFunc key_hash_func;
37
37
  FreeFunc free_key;
41
41
void
42
42
_s_map_internal_free_map_items_for_each (SMap * self,
43
43
                                         SMapItem * item,
44
 
                                         sboolean * free_data);
 
44
                                         sboolean free_data);
45
45
 
46
46
SLinkedList *
47
47
_s_map_internal_find_bucket (SMap * self,
57
57
  SMapItem * self = malloc (sizeof (SMapItem));
58
58
  self->key = key;
59
59
  self->value = value;
60
 
  
 
60
 
61
61
  return self;
62
62
}
63
63
 
65
65
s_map_item_free (SMapItem * self,
66
66
                 FreeFunc free_key,
67
67
                 FreeFunc free_value) {
68
 
  free_key (self->key);
69
 
  free_value (self->value);
 
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
  }
70
75
  free (self);
71
76
}
72
77
 
73
 
 
 
78
void
 
79
_internal_s_map_free_buckets (SLinkedList * self);
74
80
 
75
81
SMap *
76
82
s_map_new (CompFunc comp_func,
77
83
           HashFunc key_hash_func,
78
84
           FreeFunc free_key,
79
85
           FreeFunc free_value) {
 
86
  s_dbg_print ("Freeing SMap");
80
87
  SMap * self = malloc (sizeof (SMap));
81
88
  self->len = 0;
82
 
  
 
89
 
83
90
  self->is_equal = comp_func;
84
 
  
 
91
 
85
92
  /* free_* functions need to be checked if they are null and set the pointer
86
93
   * to free or s_base_object_free ()... Have to decide which...?
87
94
   */
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
 
  
99
 
  
100
 
  /* if no func is set we have to use some other metod of 
 
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
101
99
   */
102
100
  if (key_hash_func == NULL){
103
101
    self->key_hash_func = s_hash_object;
104
102
  } else {
105
103
    self->key_hash_func = key_hash_func;
106
104
  }
107
 
  
 
105
 
108
106
  self->array = s_dynamic_array_new (S_MAP_DEFAULT_NUMBER_OF_BUCKETS,
109
 
                                     FREEFUNC(s_linked_list_free));
110
 
  
 
107
                                     FREEFUNC(_internal_s_map_free_buckets));
 
108
 
111
109
  return self;
112
110
}
113
111
 
124
122
s_map_add (SMap * self, spointer key, spointer value) {
125
123
  SDynamicArray * array = self->array;
126
124
  SMapItem * item = s_map_item_new (key, value);
127
 
  
 
125
 
128
126
  /* We have to generate a key to use as an index in the DynamicArray. */
129
127
  HashFunc hash_func = self->key_hash_func;
130
128
  hash_t hash = hash_func (key);
131
129
  /* We need to mod it with the max size of the array. */
132
130
  hash = hash % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
133
 
  
 
131
 
134
132
  if (self->len == 0) {
135
133
    /* Since we know that there are no items in the array we can skip the
136
134
     * check if the new place is taken. and just and an array to it.
137
135
     */
138
 
    SLinkedList * bucket = s_linked_list_new (NULL);
 
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");
139
139
    s_dynamic_array_set (array, hash, bucket);
140
140
    s_linked_list_append (bucket, item);
141
 
    
142
141
  } else {
 
142
    s_dbg_print ("SMap size in more than zero.");
143
143
    /* Figure out if the bucket exists. */
144
144
    SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
145
 
    
 
145
 
146
146
    if (bucket == NULL) {
147
 
      bucket = s_linked_list_new (NULL);
 
147
      s_dbg_print ("Bucket does not exist");
 
148
      bucket = s_linked_list_new (FREEFUNC(_s_map_internal_free_map_items_for_each));
148
149
    }
149
 
    
 
150
 
150
151
    if (_s_map_internal_find_item_in_bucket (self, bucket, key)) {
151
152
      s_warn_print ("Key already exists in SMap\n");
152
153
      return;
153
154
    }
 
155
    s_dbg_print ("2) Appending item to linked list");
154
156
    s_linked_list_append (bucket, item);
155
157
  }
156
158
  self->len++;
159
161
spointer
160
162
s_map_get (SMap * self, spointer key) {
161
163
  spointer ret_val = NULL;
162
 
  
 
164
 
163
165
  SLinkedList * bucket = _s_map_internal_find_bucket (self, key);
164
166
  if (bucket) {
165
167
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
167
169
      ret_val = item->value;
168
170
    }
169
171
  }
170
 
  
 
172
 
171
173
  return ret_val;
172
174
}
173
175
 
189
191
 
190
192
void
191
193
s_map_for_each (SMap * self, ForEachFunc foreach_func, spointer user_data) {
 
194
  s_dbg_print ("Running For Each on SMap");
192
195
  for (size_t i = 0; i <= s_dynamic_array_last_item (self->array); i++) {
193
196
    SLinkedList * bucket = s_dynamic_array_get (self->array, i);
194
197
    if (bucket) {
 
198
      s_dbg_print ("Found bucket");
195
199
      s_linked_list_head (bucket);
 
200
      s_dbg_print ("No of items in list: %zd.", s_linked_list_len (bucket));
196
201
      do {
197
202
        SMapItem * item = s_linked_list_get_current (bucket);
198
203
        foreach_func (self, item, user_data);
204
209
SLinkedList *
205
210
_s_map_internal_find_bucket (SMap * self,
206
211
                             spointer key) {
 
212
  s_dbg_print ("Looking for bucket");
207
213
  SLinkedList * ret_val = NULL;
208
 
  
 
214
 
209
215
  HashFunc hash_func = self->key_hash_func;
210
 
  hash_t hash = hash_func (key);
211
 
  
 
216
  hash_t hash = hash_func (key)  % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
 
217
 
212
218
  ret_val = s_dynamic_array_get (self->array, hash);
213
 
  
 
219
 
214
220
  return ret_val;
215
221
}
216
222
 
219
225
_s_map_internal_find_item_in_bucket (SMap * self,
220
226
                                     SLinkedList * bucket,
221
227
                                     spointer key) {
 
228
  s_dbg_print ("Looking for item in bucket");
222
229
  s_linked_list_head (bucket);
223
230
  do {
224
231
    SMapItem * item = SMAPITEM (s_linked_list_get_current (bucket));
 
232
 
225
233
    if (item && self->is_equal (item->key, key)) {
 
234
      s_dbg_print ("Found Item in Bucket.");
226
235
      return item;
227
236
    }
228
237
  } while (s_linked_list_next (bucket));
229
 
  
 
238
 
230
239
  return NULL;
231
240
}
232
241
 
245
254
void
246
255
_s_map_internal_free_map_items_for_each (SMap * map,
247
256
                          SMapItem * item,
248
 
                          sboolean * free_data) {
249
 
  if ((*free_data)) {
 
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");
250
261
    s_map_item_free (item, map->free_key, map->free_value);
251
262
  } else {
252
263
    free (item);
253
264
  }
254
265
}
 
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
}