src/kv_list.c

changeset 1358
dda9c330e3e5
parent 1353
5a13b9c1c57b
equal deleted inserted replaced
1357:cb25a4a12edd 1358:dda9c330e3e5
164 bool backward 164 bool backward
165 ) { 165 ) {
166 const cx_kv_list *kv_list = (const cx_kv_list*)list; 166 const cx_kv_list *kv_list = (const cx_kv_list*)list;
167 // TODO: cannot really forward, because mutating iterators must be able to remove the element 167 // TODO: cannot really forward, because mutating iterators must be able to remove the element
168 return kv_list->list_methods->iterator(list, index, backward); 168 return kv_list->list_methods->iterator(list, index, backward);
169 }
170
171 static void cx_kvl_map_deallocate(struct cx_map_s *map) {
172 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
173 kv_list->map_methods->deallocate(map);
174 kv_list->list_methods->deallocate(&kv_list->list.list_base);
175 }
176
177 static void cx_kvl_map_clear(struct cx_map_s *map) {
178 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
179 // TODO: iterate through the map elements and remove the key from the referenced list items
180 kv_list->map_methods->clear(map);
181 }
182
183 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) {
184 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
185 // insert the data into the list first (assume that insertion destroys the sorted property)
186 kv_list->list.list_base.collection.sorted = false;
187 // TODO: use the same trick as above to increase the element size temporarily to add the key to the data
188 void *node_data = kv_list->list_methods->insert_element(
189 &kv_list->list.list_base, kv_list->list.list_base.collection.size, value);
190 if (node_data == NULL) return NULL; // LCOV_EXCL_LINE
191 // then insert the key into the map, referring to the node data
192 // TODO: check if we still get a correct pointer when the list is storing pointers
193 return kv_list->map_methods->put(map, key, node_data);
194 }
195
196 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) {
197 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
198 return kv_list->map_methods->get(map, key);
199 }
200
201 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) {
202 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
203 // TODO: also remove the item from the list
204 return kv_list->map_methods->remove(map, key, targetbuf);
205 }
206
207 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) {
208 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list;
209 return kv_list->map_methods->iterator(map, type);
169 } 210 }
170 211
171 static cx_list_class cx_kv_list_class = { 212 static cx_list_class cx_kv_list_class = {
172 cx_kvl_deallocate, 213 cx_kvl_deallocate,
173 cx_kvl_insert_element, 214 cx_kvl_insert_element,
183 NULL, 224 NULL,
184 cx_kvl_reverse, 225 cx_kvl_reverse,
185 cx_kvl_iterator, 226 cx_kvl_iterator,
186 }; 227 };
187 228
229 static cx_map_class cx_kv_map_class = {
230 cx_kvl_map_deallocate,
231 cx_kvl_map_clear,
232 cx_kvl_map_put,
233 cx_kvl_map_get,
234 cx_kvl_map_remove,
235 cx_kvl_map_iterator,
236 };
237
188 CxList *cxKvListCreate( 238 CxList *cxKvListCreate(
189 const CxAllocator *allocator, 239 const CxAllocator *allocator,
190 cx_compare_func comparator, 240 cx_compare_func comparator,
191 size_t elem_size 241 size_t elem_size
192 ) { 242 ) {
209 259
210 // reallocate the map to add memory for the list back-reference 260 // reallocate the map to add memory for the list back-reference
211 struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s)); 261 struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s));
212 262
213 // reallocate the list to add memory for storing the metadata 263 // reallocate the list to add memory for storing the metadata
214 cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(cx_kv_list)); 264 cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(struct cx_kv_list_s));
215 265
216 // if any of the reallocations failed, we bail out 266 // if any of the reallocations failed, we bail out
217 if (kv_map != NULL && kv_list != NULL) { 267 if (kv_map != NULL && kv_list != NULL) {
218 map = (CxMap*) kv_map; 268 map = (CxMap*) kv_map;
219 list = (CxList*) kv_list; 269 list = (CxList*) kv_list;
227 kv_list->map = kv_map; 277 kv_list->map = kv_map;
228 kv_map->list = kv_list; 278 kv_map->list = kv_list;
229 279
230 // remember the base methods and override them 280 // remember the base methods and override them
231 kv_list->map_methods = map->cl; 281 kv_list->map_methods = map->cl;
282 map->cl = &cx_kv_map_class;
232 if (list->climpl == NULL) { 283 if (list->climpl == NULL) {
233 kv_list->list_methods = list->cl; 284 kv_list->list_methods = list->cl;
234 list->cl = &cx_kv_list_class; 285 list->cl = &cx_kv_list_class;
235 } else { 286 } else {
236 kv_list->list_methods = list->climpl; 287 kv_list->list_methods = list->climpl;
237 list->climpl = &cx_kv_list_class; 288 list->climpl = &cx_kv_list_class;
238 } 289 }
239 // TODO: override all map members
240 // and remember to set the sorted flag of the list to false in the put/emplace methods!
241 290
242 return list; 291 return list;
243 } 292 }
244 293
245 CxMap *cxKvListCreateAsMap( 294 CxMap *cxKvListCreateAsMap(

mercurial