[or-cvs] add a "smartlist" building block that picks random elements...

Roger Dingledine arma at seul.org
Sat Dec 13 01:42:46 UTC 2003


Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/common

Modified Files:
	crypto.c util.c util.h 
Log Message:
add a 'smartlist' building block that picks random elements from a list


Index: crypto.c
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- crypto.c	8 Dec 2003 23:45:37 -0000	1.45
+++ crypto.c	13 Dec 2003 01:42:44 -0000	1.46
@@ -1009,6 +1009,7 @@
   }
 }
 
+/* return a pseudo random number between 0 and max-1 */
 int crypto_pseudo_rand_int(unsigned int max) {
   unsigned int val;
   unsigned int cutoff;

Index: util.c
===================================================================
RCS file: /home/or/cvsroot/src/common/util.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- util.c	8 Dec 2003 23:45:37 -0000	1.43
+++ util.c	13 Dec 2003 01:42:44 -0000	1.44
@@ -33,7 +33,7 @@
 
 void *tor_realloc(void *ptr, size_t size) {
   void *result;
-  
+
   result = realloc(ptr, size);
   if (!result) {
     log_fn(LOG_ERR, "Out of memory. Dying.");
@@ -64,6 +64,46 @@
 }
 
 /*
+ * 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
  */
 
@@ -234,11 +274,11 @@
 void set_socket_nonblocking(int socket)
 {
 #ifdef MS_WINDOWS
-	/* Yes means no and no means yes.  Do you not want to be nonblocking? */
-	int nonblocking = 0;
-	ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
+  /* Yes means no and no means yes.  Do you not want to be nonblocking? */
+  int nonblocking = 0;
+  ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
 #else
-	fcntl(socket, F_SETFL, O_NONBLOCK);
+  fcntl(socket, F_SETFL, O_NONBLOCK);
 #endif
 }
 
@@ -378,7 +418,7 @@
         if (listener != -1)
             close(listener);
         if (connector != -1)
-	    close(connector);
+            close(connector);
         if (acceptor != -1)
             close(acceptor);
         errno = save_errno;
@@ -514,7 +554,7 @@
     log_fn(LOG_WARN,"Filename %s contains illegal characters.",filename);
     return NULL;
   }
-  
+
   if(stat(filename, &statbuf) < 0) {
     log_fn(LOG_INFO,"Could not stat %s.",filename);
     return NULL;
@@ -616,11 +656,11 @@
   }
   return uname_result;
 }
-      
+
 void daemonize(void) {
 #ifdef HAVE_DAEMON
   if (daemon(0 /* chdir to / */,
-	     0 /* Redirect std* to /dev/null */)) {
+             0 /* Redirect std* to /dev/null */)) {
     log_fn(LOG_ERR, "Daemon returned an error: %s", strerror(errno));
     exit(1);
   }

Index: util.h
===================================================================
RCS file: /home/or/cvsroot/src/common/util.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- util.h	8 Dec 2003 23:45:37 -0000	1.24
+++ util.h	13 Dec 2003 01:42:44 -0000	1.25
@@ -39,6 +39,18 @@
 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);



More information about the tor-commits mailing list