pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:1768:    struct keypair *k;    struct mapping_data *a_md = a->data;    struct mapping_data *b_md = b->data;    INT32 e;    ONERROR err;       /* First some special cases. */    if (!a_md->size || !b_md->size) return allocate_mapping(0);    if (a_md == b_md) return destructive_copy_mapping(a);    +  if (a_md->size >= b_md->size / 2) {    /* Copy the second mapping. */    res = copy_mapping(b);    SET_ONERROR(err, do_free_mapping, res);       /* Remove elements in res that aren't in a. */    NEW_MAPPING_LOOP(b_md) {    size_t h = k->hval & ( a_md->hashsize - 1);    struct keypair *k2;    for (k2 = a_md->hash[h]; k2; k2 = k2->next) {    if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) {    break;    }    }    if (!k2) {    map_delete(res, &k->ind);    }    }    UNSET_ONERROR(err); -  +  } else { +  /* Copy the first mapping */ +  res = copy_mapping(a); +  SET_ONERROR(err, do_free_mapping, res); +  +  /* Remove elements in res that aren't in b, copy values for those that +  * are. */ +  NEW_MAPPING_LOOP(a_md) { +  size_t h = k->hval & ( b_md->hashsize - 1); +  struct keypair *k2; +  for (k2 = b_md->hash[h]; k2; k2 = k2->next) { +  if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) { +  mapping_insert(res, &k2->ind, &k2->val); +  break; +  } +  } +  if (!k2) { +  map_delete(res, &k->ind); +  } +  } +  +  UNSET_ONERROR(err); +  }    return res;   }      /* NOTE: May perform destructive operations on either of the arguments    * if it has only a single reference.    */   static struct mapping *or_mappings(struct mapping *a, struct mapping *b)   {    struct mapping *res;    struct keypair *k;