/* * Copyright (c) 2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: t-ring.c,v 1.8 2002/12/13 18:43:06 ca Exp $") #include "sm/assert.h" #include "sm/test.h" #include "sm/ring.h" #include #include #define toseconds(x, y) (x.tv_sec - y.tv_sec) static void test_harness(void) { sm_ring_T r1, r2, r3, *r; int c; sm_ring_init(&r1); SM_TEST(sm_ring_succ(&r1) == &r1); SM_TEST(sm_ring_pred(&r1) == &r1); sm_ring_append(&r1, &r2); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r2); SM_TEST(sm_ring_succ(&r2) == &r1); SM_TEST(sm_ring_pred(&r2) == &r1); sm_ring_prepend(&r1, &r3); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r3); SM_TEST(sm_ring_succ(&r2) == &r3); SM_TEST(sm_ring_pred(&r2) == &r1); SM_TEST(sm_ring_succ(&r3) == &r1); SM_TEST(sm_ring_pred(&r3) == &r2); r = &r1; c = 0; do { r = sm_ring_succ(r); ++c; } while (r != &r1 && c < 10); SM_TEST(c == 3); sm_ring_delentry(&r3); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r2); SM_TEST(sm_ring_succ(&r2) == &r1); SM_TEST(sm_ring_pred(&r2) == &r1); sm_ring_delentry(&r1); SM_TEST(sm_ring_succ(&r2) == &r2); SM_TEST(sm_ring_pred(&r2) == &r2); } static void test_del(void) { sm_ring_T r1, r2, r3, *r, *rn; sm_ring_init(&r1); SM_TEST(sm_ring_succ(&r1) == &r1); SM_TEST(sm_ring_pred(&r1) == &r1); sm_ring_append(&r1, &r2); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r2); SM_TEST(sm_ring_succ(&r2) == &r1); SM_TEST(sm_ring_pred(&r2) == &r1); sm_ring_prepend(&r1, &r3); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r3); SM_TEST(sm_ring_succ(&r2) == &r3); SM_TEST(sm_ring_pred(&r2) == &r1); SM_TEST(sm_ring_succ(&r3) == &r1); SM_TEST(sm_ring_pred(&r3) == &r2); for (r = &r1; r != NULL; r = rn) { rn = sm_ring_succ(r); if (rn == r) rn = NULL; sm_ring_delentry(r); } SM_TEST(sm_ring_succ(&r1) == NULL); SM_TEST(sm_ring_pred(&r1) == NULL); SM_TEST(sm_ring_succ(&r2) == NULL); SM_TEST(sm_ring_pred(&r2) == NULL); SM_TEST(sm_ring_succ(&r3) == NULL); SM_TEST(sm_ring_pred(&r3) == NULL); } static void test_inline(void) { sm_ring_T r1, r2, r3; SM_RING_INIT(&r1); SM_TEST(sm_ring_succ(&r1) == &r1); SM_TEST(sm_ring_pred(&r1) == &r1); SM_RING_APPEND(&r1, &r2); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r2); SM_TEST(sm_ring_succ(&r2) == &r1); SM_TEST(sm_ring_pred(&r2) == &r1); SM_RING_PREPEND(&r1, &r3); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r3); SM_TEST(sm_ring_succ(&r2) == &r3); SM_TEST(sm_ring_pred(&r2) == &r1); SM_TEST(sm_ring_succ(&r3) == &r1); SM_TEST(sm_ring_pred(&r3) == &r2); sm_ring_delentry(&r3); SM_TEST(sm_ring_succ(&r1) == &r2); SM_TEST(sm_ring_pred(&r1) == &r2); SM_TEST(sm_ring_succ(&r2) == &r1); SM_TEST(sm_ring_pred(&r2) == &r1); sm_ring_delentry(&r1); SM_TEST(sm_ring_succ(&r2) == &r2); SM_TEST(sm_ring_pred(&r2) == &r2); } struct appl_S { int a_key; int a_value; sm_ring_T a_ring; }; typedef struct appl_S appl_T; #define SM_A_R(a) (&((a).a_ring)) #define SM_R_A(r) SM_RING_EMBED((r), appl_T, a_ring) #define SM_APPL_R_INIT(a) SM_RING_INIT(SM_A_R(a)) #define SM_APPL_R_APP(a, e) SM_RING_APPEND(SM_A_R(a), SM_A_R(e)) #define SM_APPL_R_PRE(a, e) SM_RING_PREPEND(SM_A_R(a), SM_A_R(e)) #define sm_appl_r_succ(a) sm_ring_succ(SM_A_R(a)) #define sm_appl_r_pred(a) sm_ring_pred(SM_A_R(a)) static void test_appl(void) { appl_T a1, a2, a3; a1.a_key = 1; a2.a_key = 2; a3.a_key = 3; a1.a_value = 11; a2.a_value = 22; a3.a_value = 33; SM_APPL_R_INIT(a1); SM_TEST(sm_appl_r_succ(a1) == SM_A_R(a1)); SM_TEST(sm_appl_r_pred(a1) == SM_A_R(a1)); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_value = 11); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_value = 11); SM_APPL_R_APP(a1, a2); SM_TEST(sm_appl_r_succ(a1) == SM_A_R(a2)); SM_TEST(sm_appl_r_pred(a1) == SM_A_R(a2)); SM_TEST(sm_appl_r_succ(a2) == SM_A_R(a1)); SM_TEST(sm_appl_r_pred(a2) == SM_A_R(a1)); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_value = 11); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_value = 11); SM_APPL_R_PRE(a1, a3); SM_TEST(sm_ring_succ(SM_A_R(a1)) == SM_A_R(a2)); SM_TEST(sm_ring_pred(SM_A_R(a1)) == SM_A_R(a3)); SM_TEST(sm_ring_succ(SM_A_R(a2)) == SM_A_R(a3)); SM_TEST(sm_ring_pred(SM_A_R(a2)) == SM_A_R(a1)); SM_TEST(sm_ring_succ(SM_A_R(a3)) == SM_A_R(a1)); SM_TEST(sm_ring_pred(SM_A_R(a3)) == SM_A_R(a2)); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_key = 3); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_value = 33); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_value = 11); SM_TEST(SM_R_A(sm_appl_r_succ(a3))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_succ(a3))->a_value = 11); SM_TEST(SM_R_A(sm_appl_r_pred(a3))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_pred(a3))->a_value = 22); sm_ring_delentry(SM_A_R(a3)); SM_TEST(sm_ring_succ(SM_A_R(a1)) == SM_A_R(a2)); SM_TEST(sm_ring_pred(SM_A_R(a1)) == SM_A_R(a2)); SM_TEST(sm_ring_succ(SM_A_R(a2)) == SM_A_R(a1)); SM_TEST(sm_ring_pred(SM_A_R(a2)) == SM_A_R(a1)); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_succ(a1))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_pred(a1))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_value = 11); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_key = 1); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_value = 11); sm_ring_delentry(SM_A_R(a1)); SM_TEST(sm_ring_succ(SM_A_R(a2)) == SM_A_R(a2)); SM_TEST(sm_ring_pred(SM_A_R(a2)) == SM_A_R(a2)); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_succ(a2))->a_value = 22); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_key = 2); SM_TEST(SM_R_A(sm_appl_r_pred(a2))->a_value = 22); } struct appl2_S { int a2_key; int a2_value; sm_ring_T a2_ring; }; typedef struct appl2_S appl2_T; #define SM_A2_R(a) (&((a).a2_ring)) #define SM_R_A2(r) SM_RING_EMBED((r), appl2_T, a2_ring) #define SM_A2_R_INIT(a) SM_RING_INIT(SM_A2_R(a)) #define SM_A2_R_APP(a, e) SM_RING_APPEND(SM_A2_R(a), SM_A2_R(e)) #define SM_A2_R_PRE(a, e) SM_RING_PREPEND(SM_A2_R(a), SM_A2_R(e)) #define sm_a2_r_succ(a) SM_R_A2(sm_ring_succ(SM_A2_R(a))) #define sm_a2_r_pred(a) SM_R_A2(sm_ring_pred(SM_A2_R(a))) #define sm_a2_r_delentry(a) sm_ring_delentry(SM_A2_R(a)) static void test_appl2(void) { appl2_T a1, a2, a3; a1.a2_key = 1; a2.a2_key = 2; a3.a2_key = 3; a1.a2_value = 11; a2.a2_value = 22; a3.a2_value = 33; SM_A2_R_INIT(a1); SM_TEST(sm_a2_r_succ(a1)->a2_key = 1); SM_TEST(sm_a2_r_succ(a1)->a2_value = 11); SM_TEST(sm_a2_r_pred(a1)->a2_key = 1); SM_TEST(sm_a2_r_pred(a1)->a2_value = 11); SM_A2_R_APP(a1, a2); SM_TEST(sm_a2_r_succ(a1)->a2_key = 2); SM_TEST(sm_a2_r_succ(a1)->a2_value = 22); SM_TEST(sm_a2_r_pred(a1)->a2_key = 2); SM_TEST(sm_a2_r_pred(a1)->a2_value = 22); SM_TEST(sm_a2_r_succ(a2)->a2_key = 1); SM_TEST(sm_a2_r_succ(a2)->a2_value = 11); SM_TEST(sm_a2_r_pred(a2)->a2_key = 1); SM_TEST(sm_a2_r_pred(a2)->a2_value = 11); SM_A2_R_PRE(a1, a3); SM_TEST(sm_a2_r_succ(a1)->a2_key = 2); SM_TEST(sm_a2_r_succ(a1)->a2_value = 22); SM_TEST(sm_a2_r_pred(a1)->a2_key = 3); SM_TEST(sm_a2_r_pred(a1)->a2_value = 33); SM_TEST(sm_a2_r_succ(a2)->a2_key = 2); SM_TEST(sm_a2_r_succ(a2)->a2_value = 22); SM_TEST(sm_a2_r_pred(a2)->a2_key = 1); SM_TEST(sm_a2_r_pred(a2)->a2_value = 11); SM_TEST(sm_a2_r_succ(a3)->a2_key = 1); SM_TEST(sm_a2_r_succ(a3)->a2_value = 11); SM_TEST(sm_a2_r_pred(a3)->a2_key = 2); SM_TEST(sm_a2_r_pred(a3)->a2_value = 22); sm_a2_r_delentry(a3); SM_TEST(sm_a2_r_succ(a1)->a2_key = 2); SM_TEST(sm_a2_r_succ(a1)->a2_value = 22); SM_TEST(sm_a2_r_pred(a1)->a2_key = 2); SM_TEST(sm_a2_r_pred(a1)->a2_value = 22); SM_TEST(sm_a2_r_succ(a2)->a2_key = 1); SM_TEST(sm_a2_r_succ(a2)->a2_value = 11); SM_TEST(sm_a2_r_pred(a2)->a2_key = 1); SM_TEST(sm_a2_r_pred(a2)->a2_value = 11); sm_a2_r_delentry(a1); SM_TEST(sm_a2_r_succ(a2)->a2_key = 2); SM_TEST(sm_a2_r_succ(a2)->a2_value = 22); SM_TEST(sm_a2_r_pred(a2)->a2_key = 2); SM_TEST(sm_a2_r_pred(a2)->a2_value = 22); sm_a2_r_delentry(a2); } int main(int argc, char *argv[]) { int i, cnt; sm_test_begin(argc, argv, "test rings"); if (argc > 1) { struct timeval t1, t2; cnt = atoi(argv[1]); if (gettimeofday(&t1, NULL) < 0) perror("gettimeofday"); for (i = 0; i < cnt; i++) test_harness(); if (gettimeofday(&t2, NULL) < 0) perror("gettimeofday"); printf("function time: %ld seconds\n", toseconds(t2, t1)); if (gettimeofday(&t1, NULL) < 0) perror("gettimeofday"); for (i = 0; i < cnt; i++) test_inline(); if (gettimeofday(&t2, NULL) < 0) perror("gettimeofday"); printf("inline time: %ld seconds\n", toseconds(t2, t1)); } else { test_del(); test_harness(); test_inline(); test_appl(); test_appl2(); } return sm_test_end(); }