/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 src/Map.c

  • Committer: Gustav Hartvigsson
  • Date: 2015-08-31 16:03:37 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20150831160337-m0amg2dy7pbnpz9v
* Finished of SMap... Sort of...
* Hid internals of SMap.
* Code cleanup of SMap.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <stdlib.h>
26
26
 
27
27
struct
28
 
SMapPrivate {
 
28
SMap {
29
29
  size_t len; // Length
30
 
  SDynamicArray * array; /* This is what holds the buckets. These buckets are
 
30
  SDynamicArray * array; /**< This is what holds the buckets. These buckets are
31
31
                          * in turn also SDynamicArrays; or in template speak:
32
32
                          * SDynamicArray<SDynamicArray<SMapItem*>*>*
33
33
                          */
 
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;
34
39
};
35
40
 
 
41
void
 
42
_s_map_internal_free_array_for_each (SDynamicArray * obj,
 
43
                                     SDynamicArray * item,
 
44
                                     SMap * self);
 
45
 
 
46
void
 
47
_s_map_internal_free_bucket_for_each (SDynamicArray * obj,
 
48
                                      SMapItem * item,
 
49
                                      SMap * self);
 
50
 
 
51
SDynamicArray *
 
52
_s_map_internal_find_bucket (SMap * self,
 
53
                             spointer key);
 
54
 
 
55
SMapItem *
 
56
_s_map_internal_find_item_in_bucket (SMap * self,
 
57
                                     SDynamicArray * bucket,
 
58
                                     spointer key);
 
59
 
36
60
SMapItem *
37
61
s_map_item_new (void * key, void * value) {
38
62
  SMapItem * self = malloc (sizeof (SMapItem));
43
67
}
44
68
 
45
69
void
46
 
s_map_item_free (SMapItem * self, FuncPointer free_key,
47
 
                                       FuncPointer free_value) {
48
 
  FREEFUNC(free_key) (self->key);
49
 
  FREEFUNC(free_value) (self->value);
 
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);
50
75
  free (self);
51
76
}
52
77
 
54
79
 
55
80
SMap *
56
81
s_map_new (CompFunc comp_func,
57
 
                  HashFunc key_hash_func,
58
 
                  FuncPointer free_key,
59
 
                  FuncPointer free_value) {
 
82
           HashFunc key_hash_func,
 
83
           FreeFunc free_key,
 
84
           FreeFunc free_value) {
60
85
  SMap * self = malloc (sizeof (SMap));
61
 
  SMapClass * klass = malloc (sizeof (SMapClass));
62
 
  
63
 
  self->priv = malloc (sizeof (SMapPrivate));
64
 
  self->priv->len = 0;
65
 
  
66
 
  klass->is_equal = comp_func;
 
86
  self->len = 0;
 
87
  
 
88
  self->is_equal = comp_func;
67
89
  
68
90
  /* free_* functions need to be checked if they are null and set the pointer
69
91
   * to free or s_base_object_free ()... Have to decide which...?
70
92
   */
71
 
  klass->free_key = free_key;
72
 
  klass->free_value = free_value;
 
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
  
73
104
  
74
105
  /* if no func is set we have to use some other metod of 
75
106
   */
76
107
  if (key_hash_func == NULL){
77
 
    klass->key_hash_func = s_hash_object;
 
108
    self->key_hash_func = s_hash_object;
78
109
  } else {
79
 
    klass->key_hash_func = key_hash_func;
 
110
    self->key_hash_func = key_hash_func;
80
111
  }
81
112
  
82
113
  /* We do our own freeing of objects. */
83
 
  self->priv->array = s_dynamic_array_new (S_MAP_DEFAULT_NUMBER_OF_BUCKETS,
 
114
  self->array = s_dynamic_array_new (S_MAP_DEFAULT_NUMBER_OF_BUCKETS,
84
115
                                           NULL);
85
116
  
86
117
  return self;
88
119
 
89
120
void
90
121
s_map_free (SMap * self) {
91
 
  
92
 
  
93
 
  free (self->priv);
94
 
  free (self->klass);
 
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);
95
126
  free (self);
96
127
}
97
128
 
98
 
 
99
129
void
100
130
s_map_add (SMap * self, spointer key, spointer value) {
101
 
  SDynamicArray * array = self->priv->array;
 
131
  SDynamicArray * array = self->array;
102
132
  SMapItem * item = s_map_item_new (key, value);
103
133
  
104
134
  /* We have to generate a key to use as an index in the DynamicArray. */
105
 
  HashFunc hash_func = self->klass->key_hash_func;
 
135
  HashFunc hash_func = self->key_hash_func;
106
136
  hash_t hash = hash_func (key);
107
137
  /* We need to mod it with the max size of the array. */
108
138
  hash = hash % S_MAP_DEFAULT_NUMBER_OF_BUCKETS;
109
139
  
110
 
  if (self->priv->len == 0) {
 
140
  if (self->len == 0) {
111
141
    /* Since we know that there are no items in the array we can skip the
112
142
     * check if the new place is taken. and just and an array to it.
113
143
     */
117
147
    
118
148
  } else {
119
149
    /* Figure out if the bucket exists. */
120
 
    SDynamicArray * bucket = NULL;
121
 
    if (s_dynamic_array_get (array, hash) == NULL) {
 
150
    SDynamicArray * bucket = _s_map_internal_find_bucket (self, key);
 
151
    
 
152
    if (bucket == NULL) {
122
153
      bucket = s_dynamic_array_new (8, NULL);
123
 
    } else {
124
 
      /* We get the bucket */
125
 
      bucket = S_DYNAMIC_ARRAY(s_dynamic_array_get (array, hash));
 
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;
126
159
    }
127
160
    size_t bucket_len = s_dynamic_array_last_item (bucket);
128
161
    s_dynamic_array_set (bucket, bucket_len, item);
131
164
 
132
165
spointer
133
166
s_map_get (SMap * self, spointer key) {
 
167
  spointer ret_val = NULL;
 
168
  
 
169
  SDynamicArray * bucket = _s_map_internal_find_bucket (self, key);
 
170
  if (bucket) {
 
171
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
 
172
    if (item) {
 
173
      ret_val = item->value;
 
174
    }
 
175
  }
 
176
  
 
177
  return ret_val;
 
178
}
 
179
 
 
180
void
 
181
s_map_remove (SMap * self, spointer key) {
 
182
  SDynamicArray * bucket = _s_map_internal_find_bucket (self, key);
 
183
  if (bucket) {
 
184
    SMapItem * item = _s_map_internal_find_item_in_bucket (self, bucket, key);
 
185
    if (item) {
 
186
      s_map_item_free (item, self->free_key, self->free_value);
 
187
      return;
 
188
    }
 
189
  }
 
190
  s_dbg_print ("Could not find item in SMap.\n");
 
191
}
 
192
 
 
193
SDynamicArray *
 
194
_s_map_internal_find_bucket (SMap * self,
 
195
                             spointer key) {
 
196
  SDynamicArray * ret_val = NULL;
 
197
  
 
198
  HashFunc hash_func = self->key_hash_func;
 
199
  hash_t hash = hash_func (key);
 
200
  
 
201
  ret_val = s_dynamic_array_get (self->array, hash);
 
202
  
 
203
  return ret_val;
 
204
}
 
205
 
 
206
SMapItem *
 
207
_s_map_internal_find_item_in_bucket (SMap * self,
 
208
                                     SDynamicArray * bucket,
 
209
                                     spointer key) {
 
210
  
 
211
  for (size_t i = 0; i <= s_dynamic_array_last_item (bucket); i++) {
 
212
    SMapItem * item = SMAPITEM (s_dynamic_array_get(bucket, i));
 
213
    if (self->is_equal (item->key, key)) {
 
214
      return item;
 
215
    }
 
216
  }
 
217
  
134
218
  return NULL;
135
219
}
136
220
 
137
221
void
138
 
s_map_remove (SMap * self, spointer key) {
139
 
  
 
222
_s_map_internal_free_array_for_each (SDynamicArray * obj,
 
223
                                     SDynamicArray * item,
 
224
                                     SMap * self) {
 
225
  s_dynamic_array_for_each (item,
 
226
                            FOREACHFUNC(_s_map_internal_free_bucket_for_each),
 
227
                            self);
 
228
  s_dynamic_array_free (item, FALSE);
 
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);
140
236
}