Branch: Tag:

2013-05-25

2013-05-25 17:26:24 by Per Hedbor <ph@opera.com>

Changed worst-case ordo of replace(array,item1,item2) from O(n^2) to O(n).

Replace uses search_array, which in turn calls
check_array_for_destruct. So, if you had an array where all elements
were replaced by the replace containing at least one object replace()
was O(n^2), not O(n).

In general check_array_for_destruct is rather unneeded, since the
comparison functions already checks for destructed objects, but I
guess that it might cause objects to be free:d slightly sooner.

646:    }   }    + static ptrdiff_t fast_array_search( struct array *v, struct svalue *s, ptrdiff_t start ) + { +  ptrdiff_t e; +  /* 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 */ +  { +  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
656:   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 -  /* 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]); +  check_destructed(s); +  return fast_array_search( v, s, start );   } -  v->type_field=t; -  } -  } -  return -1; - } +       /**    * Slice a piece of an array (conditionally destructively)
2626:    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