Branch: Tag:

2015-11-15

2015-11-15 21:03:12 by Martin Nilsson <nilsson@fastmail.com>

random(mapping) was terrible. It would first pick a random bucket and walk until it got one with content, making a bucker more likely to be selected if it was preceeded by empty ones. Then it would select randomly an item from the bucket, making items in more crowded buckets less likely to be selected. Now it simply iterates over all items for a random number of items. Probably slower, but no one is using random on mappings anyways.

2143:   PMOD_EXPORT   PIKEFUN array random(mapping m)   { -  struct mapping_data *md=m->data; -  size_t bucket, count; +     struct keypair *k; -  +  int e, count;       if(!m_sizeof(m))    SIMPLE_BAD_ARG_ERROR("random", 1, "mapping with elements in it");    -  /* Find a random, nonempty bucket */ -  bucket=my_rand(md->hashsize); -  while(! md->hash[bucket] ) -  if(++bucket > (size_t)md->hashsize) -  bucket=0; +  count = my_rand( m_sizeof(m) );    -  /* Count entries in bucket */ -  count=0; -  for(k=md->hash[bucket];k;k=k->next) count++; +  /* We could optimize this by not iterating over hash buckets we will +  not pick a member from. */    -  /* Select a random entry in this bucket */ -  count = my_rand(count); -  k=md->hash[bucket]; -  while(count-- > 0) k=k->next; -  -  /* Push result and return */ +  NEW_MAPPING_LOOP(m->data) +  { +  if(count-- < 1) +  {    push_svalue(&k->ind);    push_svalue(&k->val);    f_aggregate(2);    stack_swap();    pop_stack(); -  +  return;    } -  +  } + }      #if defined(HAVE_SETENV) && defined(HAVE_UNSETENV)   #define USE_SETENV