https://fedorahosted.org/sssd/ticket/1855

I couldn't let it this way when I saw the code :)
Patch is attached

Ondra
--
Ondrej Kos
Associate Software Engineer
Identity Management
Red Hat Czech

phone: +420-532-294-558
cell:  +420-736-417-909
ext:   82-62558
loc:   1013 Brno 1 office
irc:   okos @ #sssd #brno
From b31ab385ba890b780329cb66a732b2c775112766 Mon Sep 17 00:00:00 2001
From: Ondrej Kos <o...@redhat.com>
Date: Tue, 2 Apr 2013 17:28:32 +0200
Subject: [PATCH] DHASH: Don't use backward jumps

https://fedorahosted.org/sssd/ticket/1855
---
 dhash/dhash.c | 69 ++++++++++++++++++++++++++++++++++++++++-------------------
 dhash/dhash.h |  8 +++++++
 2 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/dhash/dhash.c b/dhash/dhash.c
index 8f7ea2dddfd4d92cf24306ace93295a443ea3a84..8a5891f4b247f20c3af2ac9aacfd8732b54bbd7a 100644
--- a/dhash/dhash.c
+++ b/dhash/dhash.c
@@ -709,32 +709,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;
+    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;
+    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;
- state_3b:
-    iter->j++;
-    goto state_2;
-
-    /* Should never reach here */
-    fprintf(stderr, "ERROR hash_iter_next reached invalid state\n");
-    return NULL;
 }
 
 struct hash_iter_context_t *new_hash_iter_context(hash_table_t *table)
diff --git a/dhash/dhash.h b/dhash/dhash.h
index baa0d6aa88b767b63018127c4ac454922fdd77d8..7f44c57f8091c70766c9d7fccb166e81b377721e 100644
--- a/dhash/dhash.h
+++ b/dhash/dhash.h
@@ -133,6 +133,14 @@ typedef enum
     HASH_ENTRY_DESTROY
 } hash_destroy_enum;
 
+typedef enum {
+    HI_STATE_0,
+    HI_STATE_1,
+    HI_STATE_2,
+    HI_STATE_3A,
+    HI_STATE_3B
+} hash_iter_state;
+
 typedef struct hash_key_t {
     hash_key_enum type;
     union {
-- 
1.8.1.4

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to