Commit 1ae84fcb authored by Roger Dingledine's avatar Roger Dingledine
Browse files

add a 'smartlist' building block that picks random elements from a list


svn:r897
parent 9c66e2bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1009,6 +1009,7 @@ void crypto_pseudo_rand(unsigned int n, unsigned char *to)
  }
}

/* return a pseudo random number between 0 and max-1 */
int crypto_pseudo_rand_int(unsigned int max) {
  unsigned int val;
  unsigned int cutoff;
+49 −9
Original line number Diff line number Diff line
@@ -63,6 +63,46 @@ char *tor_strndup(const char *s, size_t n) {
  return dup;
}

/*
 * A simple smartlist interface to make an unordered list of acceptable
 * nodes and then choose a random one.
 * smartlist_create() mallocs the list, _free() frees the list,
 * _add() adds an element, _remove() removes an element if it's there,
 * _choose() returns a random element.
 */

smartlist_t *smartlist_create(int max_elements) {
  smartlist_t *sl = tor_malloc(sizeof(smartlist_t));
  sl->list = tor_malloc(sizeof(void *) * max_elements);
  sl->num_used = 0;
  sl->max = max_elements;
  return sl;
}

void smartlist_free(smartlist_t *sl) {
  free(sl->list);
  free(sl);
}

/* add element to the list, but only if there's room */
void smartlist_add(smartlist_t *sl, void *element) {
  if(sl->num_used < sl->max)
    sl->list[sl->num_used++] = element;
}

void smartlist_remove(smartlist_t *sl, void *element) {
  int i;
  for(i=0; i < sl->num_used; i++)
    if(sl->list[i] == element)
      sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
}

void *smartlist_choose(smartlist_t *sl) {
  if(sl->num_used)
    return sl->list[crypto_pseudo_rand_int(sl->num_used)];
  return NULL; /* no elements to choose from */
}

/*
 *    String manipulation
 */
+12 −0
Original line number Diff line number Diff line
@@ -39,6 +39,18 @@ char *tor_strdup(const char *s);
char *tor_strndup(const char *s, size_t n);
#define tor_free(p) do {if(p) {free(p); (p)=NULL;}} while(0)

typedef struct {
  void **list;
  int num_used;
  int max;
} smartlist_t;

smartlist_t *smartlist_create(int max_elements);
void smartlist_free(smartlist_t *sl);
void smartlist_add(smartlist_t *sl, void *element);
void smartlist_remove(smartlist_t *sl, void *element);
void *smartlist_choose(smartlist_t *sl);

const char *eat_whitespace(const char *s);
const char *eat_whitespace_no_nl(const char *s);
const char *find_whitespace(const char *s);