INLINE_STATIC int node_hash P1(mapping_node_t *, mn) { return MAP_POINTER_HASH(mn->values[0].u.number); }
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; }