Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Jun 2007 10:12:57 GMT
From:      Fredrik Lindberg <fli@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 122016 for review
Message-ID:  <200706201012.l5KACvNt066336@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=122016

Change 122016 by fli@fli_genesis on 2007/06/20 10:12:04

	- Avoid shadowing of function names
	- const'ify key argument 
	- Add opaque callback argument to hashtbl_walk()
	- Attempt to detect changes to a hash bucket after callback
	  routine in hashtbl_walk()

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/hash.c#5 edit
.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/hash.h#5 edit

Differences ...

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/hash.c#5 (text+ko) ====

@@ -308,13 +308,13 @@
  *   len - table entries, should be a power of 2
  */
 int
-hashtbl_init(struct hashtbl *ht, size_t len, size_t grow, size_t col)
+hashtbl_init(struct hashtbl *ht, size_t len, size_t growsz, size_t col)
 {
 	size_t i;
 
 	ht->ht_buckets = malloc(sizeof(struct hashbkt) * len);
 	ht->ht_tblsz = len;
-	ht->ht_grow = grow;
+	ht->ht_grow = growsz;
 	ht->ht_col = col;
 	ht->ht_mask = len - 1;
 	ht->ht_alloc_size = 0;
@@ -342,7 +342,7 @@
 	for (i = 0; i < ht->ht_tblsz; i++) {
 		TAILQ_FOREACH(he, &ht->ht_buckets[i].hb_table, he_next) {
 			if (he->he_flags & HASHTBL_KEYDUP)
-				free(he->he_key);
+				free(he->he_key.vol);
 		}
 	}
 	SLIST_FOREACH_SAFE(hep, &ht->ht_new, hep_next, hep2) {
@@ -359,13 +359,13 @@
  *   keylen - Key length
  */
 static inline struct hashentry *
-find(struct hashtbl *ht, uint32_t hval, void *key, size_t keylen)
+find(struct hashtbl *ht, uint32_t hval, const void *key, size_t keylen)
 {
 	struct hashentry *he;
 
 	TAILQ_FOREACH(he, &ht->ht_buckets[hval].hb_table, he_next) {
 		if (keylen == he->he_keylen) {
-			if (memcmp(key, he->he_key, keylen) == 0)
+			if (memcmp(key, he->he_key.con, keylen) == 0)
 				break;
 		}
 	}
@@ -382,7 +382,8 @@
  * Returns 0 on success, on failure -1 is returned
  */
 int
-hashtbl_add(struct hashtbl *ht, void *key, size_t keylen, void *data, int flags)
+hashtbl_add(struct hashtbl *ht, const void *key, size_t keylen, void *data,
+    int flags)
 {
 	uint32_t hval;
 	struct hashentry *he;
@@ -399,11 +400,11 @@
 	he->he_flags = flags;
 
 	if (flags & HASHTBL_KEYDUP) {
-		he->he_key = malloc(keylen);
-		memcpy(he->he_key, key, keylen);
+		he->he_key.vol = malloc(keylen);
+		memcpy(he->he_key.vol, key, keylen);
 	}
 	else {
-		he->he_key = key;
+		he->he_key.con = key;
 	}
 	he->he_keylen = keylen;
 	he->he_data = data;
@@ -427,7 +428,7 @@
  * Returns 0 on success, -1 on failure (non-existing key)
  */
 int
-hashtbl_del(struct hashtbl *ht, void *key, size_t keylen)
+hashtbl_del(struct hashtbl *ht, const void *key, size_t keylen)
 {
 	uint32_t hval;
 	struct hashentry *he;
@@ -439,7 +440,7 @@
 	if (he != NULL) {
 		TAILQ_REMOVE(&ht->ht_buckets[hval].hb_table, he, he_next);
 		if (he->he_flags & HASHTBL_KEYDUP)
-			free(he->he_key);
+			free(he->he_key.vol);
 		free_he(ht, he);
 		return (0);
 	}
@@ -456,7 +457,7 @@
  * NULL is returned.
  */
 void *
-hashtbl_find(struct hashtbl *ht, void *key, size_t keylen)
+hashtbl_find(struct hashtbl *ht, const void *key, size_t keylen)
 {
 	uint32_t hval;
 	struct hashentry *he;
@@ -474,14 +475,31 @@
  *   cb - Callback function
  */
 void
-hashtbl_walk(struct hashtbl *ht, hashtbl_cb cb)
+hashtbl_walk(struct hashtbl *ht, hashtbl_cb cb, void *arg)
 {
-	struct hashentry *he, *he2;
+	struct hashentry *he, *he_tmp;
+	struct hashentry *he_head, *he_next, *he_prev;
 	size_t i;
 
 	for (i = 0; i < ht->ht_tblsz; i++) {
-		TAILQ_FOREACH_SAFE(he, &ht->ht_buckets[i].hb_table, he_next, he2) {
-			cb(ht, he->he_key, he->he_keylen, he->he_data);
+		he = he_head = TAILQ_FIRST(&ht->ht_buckets[i].hb_table);
+		while (he != NULL) {
+			he_next = TAILQ_NEXT(he, he_next);
+			he_prev = TAILQ_PREV(he, hashbkt_head, he_next);
+
+			cb(ht, he->he_key.con, he->he_keylen, he->he_data, arg);
+
+			if (he_head != TAILQ_FIRST(&ht->ht_buckets[i].hb_table)) {
+				he = he_head = TAILQ_FIRST(&ht->ht_buckets[i].hb_table);
+			}
+			else {
+				he = he_next;
+				if (he_prev != NULL) {
+					he_tmp = TAILQ_NEXT(TAILQ_NEXT(he_prev, he_next), he_next);
+					if (he_tmp != NULL && he_tmp != he_next)
+						he = he_tmp;
+				}
+			}
 		}
 	}
 }

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/hash.h#5 (text+ko) ====

@@ -36,7 +36,10 @@
 	TAILQ_ENTRY(hashentry) he_next; /* Next entry */
 	uint32_t he_hash; /* Computed hash */
 	int he_flags;
-	void *he_key;	/* Byte key */
+	union {
+		void *vol;
+		const void *con;
+	} he_key;
 	size_t he_keylen;	/* Byte Key length */
 	void *he_data;	/* Data object pointer */
 };
@@ -45,7 +48,7 @@
  * Hash bucket
  */
 struct hashbkt {
-	TAILQ_HEAD(, hashentry) hb_table;
+	TAILQ_HEAD(hashbkt_head, hashentry) hb_table;
 	uint8_t hb_len;
 };
 
@@ -75,12 +78,13 @@
 
 #define HASHTBL_KEYDUP 0x01
 
-typedef void (hashtbl_cb)(struct hashtbl *, void *, size_t, void *);
+typedef void (hashtbl_cb)(struct hashtbl *, const void *, size_t,
+    void *, void *);
 int hashtbl_init(struct hashtbl *, size_t, size_t, size_t);
 void hashtbl_destroy(struct hashtbl *);
-int hashtbl_add(struct hashtbl *, void *, size_t, void *, int);
-int hashtbl_del(struct hashtbl *, void *, size_t);
-void * hashtbl_find(struct hashtbl *, void *, size_t);
-void hashtbl_walk(struct hashtbl *, hashtbl_cb);
+int hashtbl_add(struct hashtbl *, const void *, size_t, void *, int);
+int hashtbl_del(struct hashtbl *, const void *, size_t);
+void * hashtbl_find(struct hashtbl *, const void *, size_t);
+void hashtbl_walk(struct hashtbl *, hashtbl_cb, void *);
 
 #endif /* _HASH_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706201012.l5KACvNt066336>