pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: mapping.c,v 1.174 2003/11/09 01:31:12 mast Exp $ + || $Id: mapping.c,v 1.175 2003/11/12 09:31:51 grubba Exp $   */      #include "global.h" - RCSID("$Id: mapping.c,v 1.174 2003/11/09 01:31:12 mast Exp $"); + RCSID("$Id: mapping.c,v 1.175 2003/11/12 09:31:51 grubba Exp $");   #include "main.h"   #include "object.h"   #include "mapping.h"   #include "svalue.h"   #include "array.h"   #include "pike_macros.h"   #include "pike_error.h"   #include "pike_memory.h"   #include "dynamic_buffer.h"   #include "interpret.h"
pike.git/src/mapping.c:1359:   #endif    add_ref(n->data);    n->data->valrefs++;    n->data->hardlinks++;    debug_malloc_touch(n->data);    return n;   }      #endif    + static struct mapping *subtract_mappings(struct mapping *a, struct mapping *b) + { +  struct mapping *res; +  struct keypair *k; +  struct mapping_data *a_md = a->data; +  struct mapping_data *b_md = b->data; +  INT32 e; +  +  /* First some special cases. */ +  if (!a_md->size || !b_md->size || !a_md->hashsize || !b_md->hashsize) { +  return copy_mapping(a); +  } +  if (a_md == b_md) { +  return allocate_mapping(0); +  } +  /* FIXME: The break-even point should probably be researched. */ +  if (a_md->size < b_md->size) { +  /* Add the elements in a that aren't in b. */ +  res = allocate_mapping(a_md->size); +  NEW_MAPPING_LOOP(a_md) { +  size_t h = k->hval % b_md->hashsize; +  struct keypair *k2; +  for (k2 = b_md->hash[h]; k2; k2 = k2->next) { +  if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) { +  break; +  } +  } +  if (!k2) { +  mapping_insert(res, &k->ind, &k->val); +  } +  } +  } else { +  /* Remove the elements in a that are in b. */ +  res = copy_mapping(a); +  NEW_MAPPING_LOOP(b_md) { +  map_delete(res, &k->ind); +  } +  } +  return res; + } +    PMOD_EXPORT struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op)   {    ONERROR r1,r2,r3,r4;    struct array *ai, *av;    struct array *bi, *bv;    struct array *ci, *cv;    INT32 *zipper;    struct mapping *m;      #ifdef PIKE_DEBUG    if(a->data->refs <=0)    Pike_fatal("Zero refs in mapping->data\n");    if(b->data->refs <=0)    Pike_fatal("Zero refs in mapping->data\n");   #endif    -  +  if (op == PIKE_ARRAY_OP_SUB) { +  return subtract_mappings(a, b); +  } +     ai=mapping_indices(a);    SET_ONERROR(r1,do_free_array,ai);       av=mapping_values(a);    SET_ONERROR(r2,do_free_array,av);       if(ai->size > 1)    {    zipper=get_set_order(ai);    order_array(ai, zipper);