pike.git / src / array.c

version» Context lines:

pike.git/src/array.c:410:    sizeof(struct svalue) * (v->size-index));    assert_free_svalue (ITEM(ret) + index);    if (v->refs == 1) {    /* Optimization: Steal the references. */    v->size = 0;    } else if (v->type_field & BIT_REF_TYPES) {    /* Adjust the references. */    int e = v->size;    struct svalue *s = ITEM(ret);    while (e--) { -  if (TYPEOF(*s) <= MAX_REF_TYPE) add_ref(s->u.dummy); +  if (REFCOUNTED_TYPE(TYPEOF(*s))) add_ref(s->u.dummy);    s++;    }    }    free_array(v);    v=ret;    }       array_set_index_no_free (v,index,s);       return v;
pike.git/src/array.c:639:    {    MEMMOVE((char *)(ITEM(v)+index),    (char *)(ITEM(v)+index+1),    (v->size-index-1)*sizeof(struct svalue));    }    v->size--;    return v;    }   }    + static ptrdiff_t fast_array_search( struct array *v, struct svalue *s, ptrdiff_t start ) + { +  ptrdiff_t e; +  struct svalue *ip = ITEM(v); +  for(e=start;e<v->size;e++) +  if(is_eq(ip+e,s)) +  return e; +  return -1; + } +    /**    * Search for in svalue in an array.    * @param v the array to search    * @param s the value to search for    * @param start the index to start search at    * @return the index if found, -1 otherwise    */   PMOD_EXPORT ptrdiff_t array_search(struct array *v, struct svalue *s,    ptrdiff_t start)   { -  ptrdiff_t e; -  +    #ifdef PIKE_DEBUG    if(start<0)    Pike_fatal("Start of find_index is less than zero.\n");   #endif -  -  check_destructed(s); -  +    #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(v);   #endif -  +  check_destructed(s); +     /* Why search for something that is not there?    * however, we must explicitly check for searches    * for destructed objects/functions    */    if((v->type_field & (1 << TYPEOF(*s))) ||    (UNSAFE_IS_ZERO(s) && (v->type_field & (BIT_FUNCTION|BIT_OBJECT))) ||    ( (v->type_field | (1<<TYPEOF(*s))) & BIT_OBJECT )) /* for overloading */ -  { -  if(start) -  { -  for(e=start;e<v->size;e++) -  if(is_eq(ITEM(v)+e,s)) return e; -  }else{ -  TYPE_FIELD t=0; -  for(e=0;e<v->size;e++) -  { -  if(is_eq(ITEM(v)+e,s)) return e; -  t |= 1<<TYPEOF(ITEM(v)[e]); -  } -  v->type_field=t; -  } -  } +  return fast_array_search( v, s, start );    return -1;   }      /**    * Slice a piece of an array (conditionally destructively)    * @param v the array to slice    * @param start the beginning element to be included    * @param end the element beyond the end of the slice    * @return an array consisting of v[start..end-1]    */
pike.git/src/array.c:2034: Inside #if 0
   free((char *)zipper);    return ret;      #else    add_ref(a);    add_ref(b);    return merge_array_without_order2(a,b,op);   #endif   }    + /** Remove all instances of an svalue from an array + */ + static struct array *subtract_array_svalue(struct array *a, struct svalue *b) + { +  size_t size = a->size; +  size_t from=0, to=0; +  TYPE_FIELD to_type = 1<<TYPEOF(*b); +  TYPE_FIELD type_field = 0; +  ONERROR ouch; +  struct svalue *ip=ITEM(a), *dp=ip; +  int destructive = 1; +  +  if( size == 0 ) +  return copy_array(a); +  +  if( a->refs > 1 ) +  { +  /* We only need to do anything if the value exists in the array. */ +  ssize_t off = fast_array_search( a, b, 0 ); +  TYPE_FIELD tmp; +  +  if( off == -1 ) +  /* We still need to return a new array. */ +  return copy_array(a); +  +  /* In this case we generate a new array and modify that one. */ +  destructive = 0; +  from = (size_t)off; +  tmp = a->type_field; +  a = allocate_array_no_init(size-1,0); +  a->type_field = tmp; +  SET_ONERROR( ouch, do_free_array, a ); +  dp = ITEM(a); +  +  /* Copy the part of the array that is not modified first.. */ +  for( to=0; to<from; to++, ip++, dp++) +  { +  assign_svalue_no_free(dp, ip); +  type_field |= 1<<TYPEOF(*dp); +  } +  a->size = from; +  } +  + #define MATCH_COPY(X) do { \ +  if( X ) \ +  { /* include entry */ \ +  type_field|=1<<TYPEOF(*ip); \ +  if(!destructive) \ +  assign_svalue_no_free(dp,ip); \ +  else if(ip!=dp) \ +  *dp=*ip; \ +  dp++; \ +  if( !destructive ) a->size++; \ +  } \ +  else if( destructive ) \ +  free_svalue( ip ); \ +  } while(0) +  +  +  if( UNSAFE_IS_ZERO( b ) ) +  { +  /* Remove 0-valued elements. +  Rather common, so a special case is motivated. +  +  This saves time becase there is no need to check if 'b' is zero +  for each loop. +  */ +  for( ;from<size; from++, ip++ ) +  MATCH_COPY( !UNSAFE_IS_ZERO(ip) ); +  } +  else if((a->type_field & to_type) || ((a->type_field | to_type) & BIT_OBJECT)) +  { +  for( ; from<size; from++, ip++ ) +  MATCH_COPY( !is_eq(ip,b) ); +  } +  else /* b does not exist in the array. */ +  { +  add_ref(a); +  return a; +  } + #undef MATCH_COPY +  +  if( dp != ip ) +  { +  a->type_field = type_field; +  a->size = dp-ITEM(a); +  } +  +  if( !destructive ) +  UNSET_ONERROR( ouch ); +  else +  add_ref(a); +  +  if( a->size ) +  return a; +  +  free_array(a); +  add_ref(&empty_array); +  return &empty_array; + } +    /** Subtract an array from another.   */   PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b)   {   #ifdef PIKE_DEBUG    if(d_flag > 1)    {    array_check_type_field(b);    }   #endif -  check_array_for_destruct(a); +  if( b->size == 1 ) +  return subtract_array_svalue( a, ITEM(b) );    -  if((a->type_field & b->type_field) || -  ((a->type_field | b->type_field) & BIT_OBJECT)) +  if(b->size && +  ((a->type_field & b->type_field) || +  ((a->type_field | b->type_field) & BIT_OBJECT)))    {    return merge_array_with_order(a, b, PIKE_ARRAY_OP_SUB);    }else{    if(a->refs == 1)    {    add_ref(a);    return a;    } -  return slice_array(a,0,a->size); +  return copy_array(a);    }   }    -  +    /** And two arrays together.    */   PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b)   {   #ifdef PIKE_DEBUG    if(d_flag > 1)    array_check_type_field(b);   #endif    check_array_for_destruct(a);   
pike.git/src/array.c:2289:    return a;   }      /** Add an element to the end of an array by resizing the array.    *    * @param a the array to be appended    * @param s the value to be added to the new element in the array    */   PMOD_EXPORT struct array *append_array(struct array *a, struct svalue *s)   { -  a=resize_array(a,a->size+1); -  array_set_index(a, a->size-1, s); +  INT32 size = a->size; +  a=resize_array(a, size+1); +  array_set_index(a, size, s);    return a;   }      typedef char *(* explode_searchfunc)(void *,void *,size_t);      /** Explode a string into an array by a delimiter.    *    * @param str the string to be split    * @param del the string to split str by    * @returns an array containing the elements of the split string
pike.git/src/array.c:2330:    SET_SVAL(ITEM(ret)[e], T_STRING, 0, string, string_slice(str,e,1));    }    }else{    SearchMojt mojt;    ONERROR uwp;    explode_searchfunc f = (explode_searchfunc)0;       s=str->str;    end=s+(str->len << str->size_shift);    -  ret=allocate_array(10); +  ret=allocate_array(2);    ret->size=0;       mojt=compile_memsearcher(MKPCHARP_STR(del),    del->len,    str->len,    del);    SET_ONERROR (uwp, do_free_object, mojt.container);       switch(str->size_shift)    {
pike.git/src/array.c:2401:    * elements separated by a delimiter.    *    * @param a The array containing elements to be imploded    * @param del The delimiter used to separate the array's elements in the resulting string    * @return The imploded string    *    */   PMOD_EXPORT struct pike_string *implode(struct array *a,    struct pike_string *del)   { -  INT32 len, e; +  INT32 len, e, delims;    PCHARP r;    struct pike_string *ret;    struct svalue *ae;    int max_shift = del->size_shift;       len=0; -  +  delims = 0;    -  +  +     for(e=a->size, ae=a->item; e--; ae++)    switch(TYPEOF(*ae))    {    case T_INT:    if(!ae->u.integer)    continue; /* skip zero (strings) */    /* FALLTHROUGH */    default:    Pike_error("Array element %d is not a string\n", ae-a->item);    case T_STRING: -  +  delims++;    len+=ae->u.string->len + del->len;    if(ae->u.string->size_shift > max_shift)    max_shift=ae->u.string->size_shift;    break;    } -  if(len) len-=del->len; +     -  +  if(delims) +  { +  len-=del->len; +  delims--; +  } +  +  if( a->size == 1 && TYPEOF(*ITEM(a)) == PIKE_T_STRING ) +  { +  struct pike_string * res = ITEM(a)->u.string; +  res->refs++; +  return res; +  } +     ret=begin_wide_shared_string(len,max_shift);    r=MKPCHARP_STR(ret);    len = del->len;    if((e = a->size)) -  for(ae=a->item;;ae++) +  for(ae=a->item;e--;ae++)    { -  switch(TYPEOF(*ae)) +  if (TYPEOF(*ae) == T_STRING)    { -  case T_STRING: -  { +     struct pike_string *tmp = ae->u.string;    pike_string_cpy(r,tmp);    INC_PCHARP(r,tmp->len); -  break; -  } -  default: -  case T_INT: -  if(!--e) -  goto ret; -  continue; -  } -  if(!--e) -  break; -  if(len) +  if(len && delims)    { -  +  delims--;    pike_string_cpy(r,del);    INC_PCHARP(r,len);    }    } - ret: +  } +     return low_end_shared_string(ret);   }      /** Deeply copy an array. The mapping is used for temporary storage.    */   PMOD_EXPORT struct array *copy_array_recursively(struct array *a,    struct mapping *m)   {    struct array *ret;    struct svalue aa, bb;
pike.git/src/array.c:2621:      /** Replaces all from elements in array a with to elements. Called    * from replaces when first argument is an array. The replace is applied    * desctructivly.    */   void array_replace(struct array *a,    struct svalue *from,    struct svalue *to)   {    ptrdiff_t i = -1; -  -  while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to); +  check_array_for_destruct(a); +  while((i=fast_array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);   }      #ifdef PIKE_DEBUG   PMOD_EXPORT void check_array(struct array *a)   {    INT32 e;       if(a->next && a->next->prev != a)    Pike_fatal("array->next->prev != array.\n");