Permalink
Browse files

Fixed the bugs.

  • Loading branch information...
1 parent f3a55fb commit 791ec874b55324cc67e9dbca506112b17466e404 Nick committed Feb 16, 2010
Showing with 114 additions and 140 deletions.
  1. +59 −85 src/scores.c
  2. +3 −5 src/scores.h
  3. +52 −50 tests/check_barbershop.c
View
@@ -38,22 +38,6 @@ PoolNode *pool_create(int score) {
return node;
}
-// XXX: Unused, to be removed.
-PoolNode *pool_insert_after(PoolNode *node, int score) {
- PoolNode *newnode;
- newnode = pool_create(score);
- newnode->next = node->next;
- node->next = newnode;
- return newnode;
-}
-
-PoolNode *pool_push(PoolNode *list, int score) {
- PoolNode *newnode;
- newnode = pool_create(score);
- newnode->next = list;
- return newnode;
-}
-
int pool_remove(PoolNode *list, PoolNode *node) {
while (list->next && list->next != node) {
list = list->next;
@@ -67,9 +51,9 @@ int pool_remove(PoolNode *list, PoolNode *node) {
}
}
-int pool_foreach(PoolNode *node, int(*func)(int, MemberNode*)) {
+int pool_foreach(PoolNode *node, int(*func)(int, int, MemberNode*)) {
while (node) {
- if (func(node->score, node->members) != 0) {
+ if (func(node->score, node->count, node->members) != 0) {
return -1;
}
node = node->next;
@@ -148,17 +132,15 @@ MemberNode *member_last(MemberNode *node) {
}
int find_by_score(int score, MemberNode *members, void *query) {
- // printf("find_by_score(%d, NULL, %d)\n", score, query);
return score == query;
}
int find_item(int item, void *query) {
- // printf("find_item(%d, %d)\n", item, query);
return item == query;
}
-int pool_print(int score, MemberNode *members) {
- printf("Pool %d\n", score);
+int pool_print(int score, int count, MemberNode *members) {
+ printf("Pool %d (count %d)\n", score, count);
member_foreach(members, member_print);
return 0;
}
@@ -168,65 +150,71 @@ int member_print(int item) {
return 0;
}
-int preparePromotion(PoolNode *list, int item, int score) {
- // printf("preparePromotion called.\n");
- PoolNode *listMatch;
- if ((listMatch = pool_find(list, find_by_score, (void*)score))) {
- // printf(" => found pool with score %d\n", score);
- MemberNode *memberMatch;
- if ((memberMatch = member_find(listMatch->members, find_item, (void*)item))) {
- // printf(" => found member %d in pool %d\n", item, score);
- listMatch->count--;
- member_remove(listMatch->members, memberMatch);
- return 1;
+PoolNode *preparePromotion(PoolNode *head, int item, int score) {
+ MemberNode *memberMatch;
+ if (head->score == score) {
+ if (head->members->item == item) {
+ memberMatch = head->members;
+ head->members = memberMatch->next;
+ head->count -= 1;
+ } else {
+ if ((memberMatch = member_find(head->members, find_item, (void*)item))) {
+ head->count -= 1;
+ assert(member_remove(head->members, memberMatch) == 0);
+ }
+ }
+ if (head->count == 0) {
+ return head->next;
+ }
+ } else {
+ PoolNode *listMatch;
+ if ((listMatch = pool_find(head, find_by_score, (void*)score))) {
+ if (listMatch->count == 1) {
+ assert(pool_remove(head, listMatch) == 0);
+ return 1;
+ } else {
+ if ((memberMatch = member_find(listMatch->members, find_item, (void*)item))) {
+ listMatch->count -= 1;
+ assert(member_remove(listMatch->members, memberMatch) == 0);
+ return 1;
+ }
+ return 0;
+ }
}
}
- return 0;
+ return head;
}
PoolNode *promoteItem(PoolNode *list, int score, int item, int old_score) {
if (old_score != -1) {
- preparePromotion(list, item, old_score);
+ list = preparePromotion(list, item, old_score);
}
- // printf("promoteItem called.\n");
if (list == NULL) {
- // printf(" -> list is NULL\n");
PoolNode *newPool;
newPool = pool_create(score);
- // printf(" -> Created newPool (score=%d)\n", newPool->score);
MemberNode *newMember;
newMember = member_create(item);
- // printf(" -> Created newMember (item=%d)\n", newMember->item);
newPool->members = newMember;
newPool->count++;
return newPool;
}
PoolNode *listMatch;
- // printf(" -> looking for score %d.\n", score);
if ((listMatch = pool_find(list, find_by_score, (void*)score))) {
- // printf(" -> score pool exists (score=%d)\n", listMatch->score);
MemberNode *memberMatch;
if ((memberMatch = member_find(listMatch->members, find_item, (void*)item))) {
- // printf(" -> item exists in pool\n");
} else {
- // printf(" -> item does not exist in pool\n");
assert(listMatch != NULL);
assert(listMatch->members != NULL);
listMatch->members = member_push(listMatch->members, item);
- // printf(" -> new member created (item=%d)\n", listMatch->members->item);
listMatch->count++;
- // printf(" -> pool %d has %d members\n", listMatch->score, listMatch->count);
}
return list;
} else {
// Score pool doesn't exist
- // printf(" -> score pool doesn't exist\n");
PoolNode *newPool;
newPool = pool_create(score);
- // printf(" -> Created newPool (score=%d)\n", newPool->score);
MemberNode *newMember;
newMember = member_create(item);
- // printf(" -> Created newMember (item=%d)\n", newMember->item);
newPool->members = newMember;
newPool->count++;
newPool->next = list;
@@ -235,44 +223,30 @@ PoolNode *promoteItem(PoolNode *list, int score, int item, int old_score) {
return NULL;
}
-// int NextItem(PoolNode *list) {
-// if (! list) { return -1; }
-// while (list->next && list->count > 0) {
-// list = list->next;
-// }
-// if (list != NULL && list->members != NULL) {
-// MemberNode *last = member_last(list->members);
-// int item_id = last->item;
-// list->count--;
-// if (list->members == 1) {
-// free(last);
-// list->members = NULL;
-// } else {
-// member_remove(list->members, last);
-// }
-// return item_id;
-// } else{
-// return -1;
-// }
-// }
-
-PoolNode *NextItem(PoolNode *list, int *next_item) {
- if (list == NULL) { next_item = -1; return list; }
- while (list->next && list->count == 0) {
- list = list->next;
+PoolNode *NextItem(PoolNode *head, int *next_item) {
+ if (head == NULL) {
+ *next_item = -1;
+ return NULL;
}
- if (list != NULL && list->members != NULL) {
- printf("We got this far ...\n");
- MemberNode *last = member_last(list->members);
- next_item = last->item;
- printf("and now ...\n");
- member_remove(list->members, next_item);
- printf("and now ...\n");
- if (list->members != NULL) { printf("first member item is %d\n", list->members->item); }
- printf("count at %d\n", list->count);
- list->count--;
- return list;
+ assert(head != NULL);
+ if (head->count == 1)
+ {
+ // If the head has one member then set the next_item to the
+ // members->item value and return head->next
+ *next_item = head->members->item;
+ return head->next;
+ }
+ else
+ {
+ // If the head has more than one member then
+ // * get the value of the last members->item
+ // * remove the last member of the head->members chain
+ // * return head
+ MemberNode *last = member_last(head->members);
+ *next_item = last->item;
+ assert(member_remove(head->members, last) == 0);
+ head->count -= 1;
+ return head;
}
- return list;
}
View
@@ -36,10 +36,8 @@ typedef struct node_pool {
} PoolNode;
PoolNode *pool_create(int score);
-PoolNode *pool_insert_after(PoolNode *node, int score);
-PoolNode *pool_push(PoolNode *list, int score);
int pool_remove(PoolNode *list, PoolNode *node);
-int pool_foreach(PoolNode *node, int(*func)(int, MemberNode*));
+int pool_foreach(PoolNode *node, int(*func)(int, int, MemberNode*));
PoolNode *pool_find(PoolNode *node, int(*func)(int, MemberNode*,void*), void *data);
MemberNode *member_create(int item);
@@ -52,10 +50,10 @@ MemberNode *member_last(MemberNode *node);
int find_by_score(int score, MemberNode *members, void *query);
int find_item(int item, void *query);
-int pool_print(int score, MemberNode *members);
+int pool_print(int score, int count, MemberNode *members);
int member_print(int item);
-int preparePromotion(PoolNode *list, int item, int score);
+PoolNode *preparePromotion(PoolNode *head, int item, int score);
PoolNode *promoteItem(PoolNode *list, int score, int item, int old_score);
PoolNode *NextItem(PoolNode *list, int *next_item);
@@ -13,66 +13,68 @@ START_TEST (test_pools_empty) {
} END_TEST
// Assert that counts are maintained while adding.
-START_TEST (test_pools_add) {
- PoolNode *head_b = NULL;
- int next = -1;
- head_b = promoteItem(head_b, 1, 5000, -1);
- fail_if(head_b->score != 1);
- fail_if(head_b->count != 1);
- head_b = NextItem(head_b, &next);
- printf("next %d\n", next);
+START_TEST(test_pools_add) {
+ PoolNode *b = NULL;
+ int next;
+ b = promoteItem(b, 1, 5000, -1);
+ fail_if(b->score != 1);
+ fail_if(b->count != 1);
+ b = NextItem(b, &next);
+ fail_unless(b == NULL);
fail_unless(next == 5000);
- pool_foreach(head_b, pool_print);
- fail_if(head_b->score != 1);
- fail_if(head_b->count != 0);
- head_b = NextItem(head_b, &next);
- printf("next %d\n", next);
+ b = NextItem(b, &next);
fail_unless(next == -1);
- fail_if(head_b->score != 1);
- fail_if(head_b->count != 0);
} END_TEST
-//
-// // Assert insert order is maintained.
-// START_TEST (test_pools_add_several) {
-// PoolNode *head_c = NULL;
-// head_c = promoteItem(head_c, 1, 5000, -1);
-// fail_if(head_c->score != 1);
-// fail_if(head_c->count != 1);
-// head_c = promoteItem(head_c, 1, 5001, -1);
-// fail_if(head_c->count != 2);
-// head_c = promoteItem(head_c, 1, 5002, -1);
-// fail_if(head_c->score != 1);
-// fail_if(head_c->count != 3);
-// fail_unless(NextItem(head_c) == 5000);
-// fail_if(head_c->count != 2);
-// fail_unless(NextItem(head_c) == 5001);
-// fail_if(head_c->count != 1);
-// fail_unless(NextItem(head_c) == 5002);
-// fail_if(head_c->count != 0);
-// } END_TEST
-//
+
+// Assert insert order is maintained.
+START_TEST (test_pools_add_several) {
+ PoolNode *head_c = NULL;
+ head_c = promoteItem(head_c, 1, 5000, -1);
+ fail_if(head_c->score != 1);
+ fail_if(head_c->count != 1);
+ head_c = promoteItem(head_c, 1, 5001, -1);
+ fail_if(head_c->count != 2);
+ head_c = promoteItem(head_c, 1, 5002, -1);
+ fail_if(head_c->score != 1);
+ fail_if(head_c->count != 3);
+ int next = -1;
+ head_c = NextItem(head_c, &next);
+ fail_unless(next == 5000);
+ fail_if(head_c->count != 2);
+ head_c = NextItem(head_c, &next);
+ fail_unless(next == 5001);
+ fail_if(head_c->count != 1);
+ head_c = NextItem(head_c, &next);
+ fail_unless(next == 5002);
+} END_TEST
+
// // Assert promoting ensures accurate counts and membership
-// START_TEST (test_pools_promote) {
-// PoolNode *head_d = NULL;
-// head_d = promoteItem(head_d, 1, 5000, -1);
-// head_d = promoteItem(head_d, 1, 5001, -1);
-// head_d = promoteItem(head_d, 2, 5000, 1);
-// head_d = promoteItem(head_d, 3, 5000, 2);
-// fail_if(head_d->score != 3);
-// fail_if(head_d->count != 1);
-// fail_if(head_d->next->score != 2);
-// fail_if(head_d->next->count != 0);
-// fail_if(head_d->next->next->score != 1);
-// fail_if(head_d->next->next->count != 1);
-// } END_TEST
+START_TEST (test_pools_promote) {
+ PoolNode *head_d = NULL;
+ head_d = promoteItem(head_d, 1, 5000, -1);
+ head_d = promoteItem(head_d, 1, 5001, -1);
+ head_d = promoteItem(head_d, 2, 5000, 1);
+ head_d = promoteItem(head_d, 3, 5000, 2);
+ fail_if(head_d->score != 3);
+ fail_if(head_d->count != 1);
+ fail_if(head_d->next->score != 1);
+ fail_if(head_d->next->count != 1);
+ int next;
+ head_d = NextItem(head_d, &next);
+ fail_unless(next == 5000);
+ head_d = NextItem(head_d, &next);
+ fail_unless(next == 5001);
+ head_d = NextItem(head_d, &next);
+ fail_unless(next == -1);
+} END_TEST
Suite * barbershop_suite(void) {
Suite *s = suite_create("Barbershop");
TCase *tc_core = tcase_create("Core");
tcase_add_test(tc_core, test_pools_empty);
tcase_add_test(tc_core, test_pools_add);
- // tcase_add_test(tc_core, test_pools_add_several);
- // tcase_add_test(tc_core, test_pools_promote);
+ tcase_add_test(tc_core, test_pools_add_several);
+ tcase_add_test(tc_core, test_pools_promote);
suite_add_tcase(s, tc_core);
return s;
}

0 comments on commit 791ec87

Please sign in to comment.