/** * ml_add - adds a new MEntry to the list; * returns 1 if successful, 0 if error (calloc) * returns 1 if it is a duplicate **/ int ml_add(MList **ml, MEntry *me) { MLinkList *t = (*ml)->hash_table; // temporary reference to hash table in mail list MListNode *n; unsigned long hash = me_hash(me, (*ml)->size); if (ml_verbose) fprintf(stderr, "mlist: add entry\n"); if (ml_lookup((*ml), me) != NULL) // return 1 if it is a duplicate return 1; if ((n = (MListNode *) calloc(1, sizeof(MListNode))) == NULL) // return 0 if error (calloc) return 0; n->entry = me; n->next = t[hash].first; // add first node of the bucket to next reference of the new node t[hash].first = n; // set the head of bucket to be the new node if (!(t[hash].last)) // if there is only one item in the bucket t[hash].last = n; // then set head and tail of the bucket to point to the node ++t[hash].size; if (t[hash].size > MAX_COLLISION) { // if the bucket size is over the limit, then re-size and re-hash MLinkList *old_t, *new_t; MListNode *cur, *freed; unsigned long i, old_size = (*ml)->size, new_size = (*ml)->size * GROWTH_TIMES; if (ml_verbose) fprintf(stderr, "mlist: re-hash table from size %lu to %lu\n", (*ml)->size, new_size); if ((new_t = (MLinkList *) calloc(new_size, sizeof(MLinkList))) != NULL) { old_t = (*ml)->hash_table; (*ml)->hash_table = new_t; (*ml)->size = new_size; for (i = 0; i < old_size; ++i) { for (cur = old_t[i].first; cur != NULL;) { ml_add(ml, cur->entry); freed = cur; cur = cur->next; free((void *) freed); } } free((void *) old_t); } } return 1; }
int main(int argc, char *argv[]) { MEntry *mep, *meq; MList *ml; char *p; int c; int varg = 0; if (argc > 2) { usage(); return -1; } if (argc == 2) { p = argv[1]; if (*p++ != '-') { usage(); return -1; } while ((c = *p++) != '\0') { if (c =='v' || c == 'V') varg++; else { fprintf(stderr, "Illegal flag: %c\n", c); usage(); return -1; } } } ml_verbose = varg; ml = ml_create(); while ((mep = me_get(stdin)) != NULL) { meq = ml_lookup(ml, mep); if (meq == NULL) (void) ml_add(&ml, mep); else { printf("Potential duplicate\n"); printf("===================\n"); me_print(mep, stdout); printf("==========\n"); me_print(meq, stdout); printf("\n"); me_destroy(mep); } } ml_destroy(ml); return 0; }