static State *addhash(hash_table *ht, char* prefix[NPREF], uint32_t hv){ int ind = hv % ht->len; State *temp; if(temp = ht->table[ind]){ do { if(prefix_compare(temp->pref, prefix)){ return temp; } } while (temp->next && (temp = temp->next)); } if(!temp){ ht->table[ind] = emalloc(sizeof(State)); temp = ht->table[ind]; } else { temp->next = emalloc(sizeof(State)); temp = temp->next; } memcpy(temp->pref,prefix,NPREF*sizeof(char*)); temp->next = NULL; temp->hv = hv; ht->entries++; if((float)ht->entries/ht->len > ht->load_factor){ rehash(ht); } return temp; }
static condition_t * find_access_list (int num, int permit, prefix_t *prefix, prefix_t *wildcard, int exact, int refine) { condition_t *condition; if (num < 0 || num >= MAX_ALIST) return (NULL); if (access_list[num] == NULL) { return (NULL); } LL_Iterate (access_list[num], condition) { if (permit != condition->permit) continue; if (prefix == NULL && condition->prefix == NULL) { /* OK, both are all */ } else if (prefix && condition->prefix) { if (!prefix_compare (prefix, condition->prefix)) continue; if (wildcard == NULL && condition->wildcard == NULL) { /* OK */ } else if (wildcard && condition->wildcard) { if (!prefix_compare (wildcard, condition->wildcard)) continue; } else { continue; } if (exact != condition->exact) continue; if (refine != condition->refine) continue; } else { /* one is prefix, the other is all */ continue; } return (condition); } return (NULL); }
/* creation doesn't strdup so strings mustn't change later. */ static State* ht_lookup(char *prefix[NPREF], int create, PrefixStorer* ps) { State *temp; hash_table *ht = ps->tableBase; uint32_t hv = ps->hash(prefix); if(create){ return addhash(ht,prefix,hv); } temp = ht->table[hv % ht->len]; if(temp){ do { if(temp->hv == hv){ if(prefix_compare(temp->pref, prefix)){ return temp; } } } while (temp->next && (temp = temp->next)); } return NULL; }