[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8396: Implement a smartlist_uniq() that will with luck not end the (in tor/trunk: . doc src/common src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8396: Implement a smartlist_uniq() that will with luck not end the (in tor/trunk: . doc src/common src/or)
- From: nickm@xxxxxxxx
- Date: Fri, 15 Sep 2006 00:28:04 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Fri, 15 Sep 2006 00:28:19 -0400
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-09-15 00:27:58 -0400 (Fri, 15 Sep 2006)
New Revision: 8396
Modified:
tor/trunk/
tor/trunk/doc/TODO
tor/trunk/src/common/container.c
tor/trunk/src/common/container.h
tor/trunk/src/or/router.c
tor/trunk/src/or/routerparse.c
Log:
r8819@Kushana: nickm | 2006-09-15 00:27:45 -0400
Implement a smartlist_uniq() that will with luck not end the world.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r8819] on c95137ef-5f19-0410-b913-86e773d04f59
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2006-09-14 22:34:57 UTC (rev 8395)
+++ tor/trunk/doc/TODO 2006-09-15 04:27:58 UTC (rev 8396)
@@ -284,7 +284,7 @@
- stop writing identity key / fingerprint / etc every restart
- stop caching directory stuff -- and disable mmap?
- more?
- - smartlist_uniq(): We have at least 3 places that check a smartlist for
+ o smartlist_uniq(): We have at least 3 places that check a smartlist for
duplicates and then removes them: networkstatus_parse_from_string(),
sort_version_list(), and router_rebuild_descriptor(). This should probably
get its own function that takes a comparator and a delete function.
Modified: tor/trunk/src/common/container.c
===================================================================
--- tor/trunk/src/common/container.c 2006-09-14 22:34:57 UTC (rev 8395)
+++ tor/trunk/src/common/container.c 2006-09-15 04:27:58 UTC (rev 8396)
@@ -429,6 +429,29 @@
(int (*)(const void *,const void*))compare);
}
+/** Given a sorted smartlist <b>sl</b> and the comparison function used to
+ * sort it, remove all duplicate members. If free_fn is provided, calls
+ * free_fn on each duplicate. Otherwise, frees them with tor_free(), which
+ * may not be what you want.. Preserves order.
+ */
+void
+smartlist_uniq(smartlist_t *sl,
+ int (*compare)(const void **a, const void **b),
+ void (*free_fn)(void *a))
+{
+ int i;
+ for (i=1; i < sl->num_used; ++i) {
+ if (compare((const void **)&(sl->list[i-1]),
+ (const void **)&(sl->list[i])) == 0) {
+ if (free_fn)
+ free_fn(sl->list[i]);
+ else
+ tor_free(sl->list[i]);
+ smartlist_del_keeporder(sl, i--);
+ }
+ }
+}
+
/** Assuming the members of <b>sl</b> are in order, return a pointer to the
* member which matches <b>key</b>. Ordering and matching are defined by a
* <b>compare</b> function, which returns 0 on a match; less than 0 if key is
@@ -462,6 +485,14 @@
smartlist_sort(sl, _compare_string_ptrs);
}
+/** Remove duplicate strings from a sorted list, and free them with tor_free().
+ */
+void
+smartlist_uniq_strings(smartlist_t *sl)
+{
+ smartlist_uniq(sl, _compare_string_ptrs, NULL);
+}
+
#define LEFT_CHILD(i) ( ((i)+1)*2 - 1)
#define RIGHT_CHILD(i) ( ((i)+1)*2 )
#define PARENT(i) ( ((i)+1)/2 - 1)
@@ -557,6 +588,14 @@
smartlist_sort(sl, _compare_digests);
}
+/** Remove duplicate digests from a sorted list, and free them with tor_free().
+ */
+void
+smartlist_uniq_digests(smartlist_t *sl)
+{
+ smartlist_uniq(sl, _compare_digests, NULL);
+}
+
#define DEFINE_MAP_STRUCTS(maptype, keydecl, prefix) \
typedef struct prefix ## entry_t { \
HT_ENTRY(prefix ## entry_t) node; \
Modified: tor/trunk/src/common/container.h
===================================================================
--- tor/trunk/src/common/container.h 2006-09-14 22:34:57 UTC (rev 8395)
+++ tor/trunk/src/common/container.h 2006-09-15 04:27:58 UTC (rev 8396)
@@ -74,8 +74,13 @@
void smartlist_insert(smartlist_t *sl, int idx, void *val);
void smartlist_sort(smartlist_t *sl,
int (*compare)(const void **a, const void **b));
+void smartlist_uniq(smartlist_t *sl,
+ int (*compare)(const void **a, const void **b),
+ void (*free_fn)(void *elt));
void smartlist_sort_strings(smartlist_t *sl);
void smartlist_sort_digests(smartlist_t *sl);
+void smartlist_uniq_strings(smartlist_t *sl);
+void smartlist_uniq_digests(smartlist_t *sl);
void *smartlist_bsearch(smartlist_t *sl, const void *key,
int (*compare)(const void *key, const void **member))
ATTR_PURE;
Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c 2006-09-14 22:34:57 UTC (rev 8395)
+++ tor/trunk/src/or/router.c 2006-09-15 04:27:58 UTC (rev 8396)
@@ -804,7 +804,6 @@
if (authdir_mode(options))
ri->is_valid = ri->is_named = 1; /* believe in yourself */
if (options->MyFamily) {
- int i;
smartlist_t *family;
if (!warned_nonexistent_family)
warned_nonexistent_family = smartlist_create();
@@ -844,15 +843,7 @@
/* remove duplicates from the list */
smartlist_sort_strings(ri->declared_family);
- for (i = 1; i < smartlist_len(ri->declared_family); ++i) {
- const char *a, *b;
- a = smartlist_get(ri->declared_family, i-1);
- b = smartlist_get(ri->declared_family, i);
- if (!strcmp(a,b)) {
- tor_free(smartlist_get(ri->declared_family, i));
- smartlist_del_keeporder(ri->declared_family, i--);
- }
- }
+ smartlist_uniq_strings(ri->declared_family);
smartlist_free(family);
}
Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c 2006-09-14 22:34:57 UTC (rev 8395)
+++ tor/trunk/src/or/routerparse.c 2006-09-15 04:27:58 UTC (rev 8396)
@@ -1075,6 +1075,15 @@
return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
}
+static void
+_free_duplicate_routerstatus_entry(void *e)
+{
+ log_warn(LD_DIR,
+ "Network-status has two entries for the same router. "
+ "Dropping one.");
+ routerstatus_free(e);
+}
+
/** Given a versioned (v2 or later) network-status object in <b>s</b>, try to
* parse it and return the result. Return NULL on failure. Check the
* signature of the network status, but do not (yet) check the signing key for
@@ -1217,21 +1226,9 @@
smartlist_add(ns->entries, rs);
}
smartlist_sort(ns->entries, _compare_routerstatus_entries);
+ smartlist_uniq(ns->entries, _compare_routerstatus_entries,
+ _free_duplicate_routerstatus_entry);
- /* Kill duplicate entries. */
- for (i=0; i < smartlist_len(ns->entries)-1; ++i) {
- routerstatus_t *rs1 = smartlist_get(ns->entries, i);
- routerstatus_t *rs2 = smartlist_get(ns->entries, i+1);
- if (!memcmp(rs1->identity_digest,
- rs2->identity_digest, DIGEST_LEN)) {
- log_warn(LD_DIR,
- "Network-status has two entries for the same router. "
- "Dropping one.");
- smartlist_del_keeporder(ns->entries, i--);
- routerstatus_free(rs1);
- }
- }
-
if (tokenize_string(s, NULL, tokens, NETSTATUS)) {
log_warn(LD_DIR, "Error tokenizing network-status footer.");
goto err;
@@ -1922,22 +1919,9 @@
void
sort_version_list(smartlist_t *versions, int remove_duplicates)
{
- int i;
-
smartlist_sort(versions, _compare_tor_version_str_ptr);
- if (!remove_duplicates)
- return;
- for (i = 1; i < smartlist_len(versions); ++i) {
- const void *a, *b;
- a = smartlist_get(versions, i-1);
- b = smartlist_get(versions, i);
- /* use version_cmp so we catch multiple representations of the same
- * version */
- if (_compare_tor_version_str_ptr(&a,&b) == 0) {
- tor_free(smartlist_get(versions, i));
- smartlist_del_keeporder(versions, i--);
- }
- }
+ if (remove_duplicates)
+ smartlist_uniq(versions, _compare_tor_version_str_ptr, NULL);
}