pike.git
/
src
/
builtin.cmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/builtin.cmod:2136:
pop_stack(); } /*! @decl array random(mapping m) *! Returns a random index-value pair from the mapping. */ 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 #else /* Used to hold refs to the strings that we feed to putenv. Indexed on * variable names, values are the "name=value" strings. * * This is not needed when using {,un}setenv(), since they maintain * their own corresponding table. */ static struct mapping *env_allocs = NULL;