From f8a80797c298f4ebe2dc2ebcb2327fa1f3a38905 Mon Sep 17 00:00:00 2001 From: Ondrej Kos Date: Tue, 2 Apr 2013 17:28:32 +0200 Subject: DHASH: Don't use backward jumps https://fedorahosted.org/sssd/ticket/1855 --- dhash/dhash.c | 79 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/dhash/dhash.c b/dhash/dhash.c index 72709af..ab1bebc 100644 --- a/dhash/dhash.c +++ b/dhash/dhash.c @@ -124,6 +124,14 @@ struct _hash_iter_context_t { element_t *p; }; +enum hash_iter_state { + HI_STATE_0, + HI_STATE_1, + HI_STATE_2, + HI_STATE_3A, + HI_STATE_3B +}; + /*****************************************************************************/ /********************** External Function Declarations *********************/ /*****************************************************************************/ @@ -709,32 +717,57 @@ static hash_entry_t *hash_iter_next(struct hash_iter_context_t *iter_arg) { struct _hash_iter_context_t *iter = (struct _hash_iter_context_t *) iter_arg; hash_entry_t *entry; + enum hash_iter_state state = HI_STATE_3A; if (iter->table == NULL) return NULL; - goto state_3a; - - state_1: - iter->i++; - if(iter->i >= iter->table->segment_count) return NULL; - /* test probably unnecessary */ - iter->s = iter->table->directory[iter->i]; - if (iter->s == NULL) goto state_1; - iter->j = 0; - state_2: - if (iter->j >= iter->table->segment_size) goto state_1; - iter->p = iter->s[iter->j]; - state_3a: - if (iter->p == NULL) goto state_3b; - entry = &iter->p->entry; - iter->p = iter->p->next; - return entry; - state_3b: - iter->j++; - goto state_2; - /* Should never reach here */ - fprintf(stderr, "ERROR hash_iter_next reached invalid state\n"); - return NULL; + while (state != HI_STATE_0) { + + switch (state) { + case HI_STATE_1: + iter->i++; + if(iter->i >= iter->table->segment_count) return NULL; + /* test probably unnecessary */ + iter->s = iter->table->directory[iter->i]; + if (iter->s == NULL) { + state = HI_STATE_1; + break; + } + iter->j = 0; + state = HI_STATE_2; + + case HI_STATE_2: + if (iter->j >= iter->table->segment_size) { + state = HI_STATE_1; + break; + } + iter->p = iter->s[iter->j]; + state = HI_STATE_3A; + + case HI_STATE_3A: + if (iter->p == NULL) { + state = HI_STATE_3B; + break; + } + entry = &iter->p->entry; + iter->p = iter->p->next; + state = HI_STATE_0; + break; + + case HI_STATE_3B: + iter->j++; + state = HI_STATE_2; + break; + + default: + /* Should never reach here */ + fprintf(stderr, "ERROR hash_iter_next reached invalid state\n"); + return NULL; + break; + } + } + + return entry; } struct hash_iter_context_t *new_hash_iter_context(hash_table_t *table) -- cgit