int map_set(struct map_t* map, const char* key, void* value) { const struct map_find_results_t find_result = map_find(map, key); // found node with same key if (find_result.exact_match) { if (map->free_func && find_result.node->value) { (*map->free_func)(find_result.node->value); } find_result.node->value = value; return 0; } // create the new node. struct map_node_t* new_node = new_map_node(key, value); if (!new_node) { return -1; } // empty list if (map->head == NULL) { map->head = new_node; map->size = 1; return 0; } // put the new node in the proper place struct map_node_t* node = find_result.node; struct map_node_t* prev_node = find_result.prev_node; new_node->next = node; if (prev_node) { prev_node->next = new_node; } else { map->head = new_node; } map->size++; return 0; }
INLINE void bson_to_mapping P2(const char *, data, svalue_t *, v){ int id; int oi; int mask; int size; int count = 0; const char *key_c; bson_iterator i; mapping_t *m; svalue_t key, value; mapping_node_t **a, *elt, *elt2; size = sizeof_bson(data); if (!size) { v->type = T_MAPPING; v->u.map = allocate_mapping(0); return; } m = allocate_mapping(size); a = m->table; mask = m->table_size; bson_iterator_from_buffer( &i, data ); while(bson_iterator_next( &i )){ key_c = bson_iterator_key( &i ); key.u.string = make_shared_string(key_c); key.type = T_STRING; key.subtype = STRING_SHARED; bson_to_v(&i,&value); oi = MAP_POINTER_HASH(key.u.number); id = oi & mask; if ((elt2 = elt = a[id])) { do { /* This should never happen, but don't bail on it */ if (msameval(&key, elt->values)) { free_svalue(&key, "bson_to_map: duplicate key"); free_svalue(elt->values+1, "bson_to_map: replaced value"); *(elt->values+1) = value; break; } } while ((elt = elt->next)); if (elt) continue; } else if (!(--m->unfilled)) { if (growMap(m)) { a = m->table; if (oi & ++mask) elt2 = a[id |= mask]; mask <<= 1; mask--; } else { add_map_stats(m, count); free_mapping(m); free_svalue(&key, "bson_to_map: out of memory"); free_svalue(&value, "bson_to_map: out of memory"); error("Out of memory\n"); } } if (++count > MAX_MAPPING_SIZE) { add_map_stats(m, count -1); free_mapping(m); free_svalue(&key, "bson_to_map: mapping too large"); free_svalue(&value, "bson_to_map: mapping too large"); mapping_too_large(); } elt = new_map_node(); *elt->values = key; *(elt->values + 1) = value; (a[id] = elt)->next = elt2; } add_map_stats(m, count); v->type = T_MAPPING; v->u.map = m; }