/* * Copyright (c) 2002, 2004, 2005 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-rsc-1.c,v 1.16 2005/05/31 21:00:28 ca Exp $") #include #include "sm/memops.h" #include "sm/assert.h" #include "sm/rpool.h" #include "sm/rsc.h" #include "sm/test.h" #define CSIZE 13 #define HTSIZE 25 #define CHARS 64 #define NH 55 /* must be less than CHARS */ #define HLEN 12 #define KLEN (HLEN - 2) #define VALI(i) (((i) + 5) % NH) int Verbose = 0; char hashes[NH][HLEN]; static void * create(const char *key, uint len, void *value, void *ctx) { if (Verbose > 1) fprintf(stderr, "create(%s)=%s\n", key, (char *) value); return value; } static sm_ret_T delete(void *data, void *ctx) { if (Verbose > 1) fprintf(stderr, "delete(%s)\n", (char *)data); return SM_SUCCESS; } static int cnt = 0; static void action(const char *key, const void *value, void *ctx, void *walk_ctx) { if (Verbose > 1) fprintf(stderr, "action(%s)=%s\n", key, (char *) value); ++cnt; } static void testh(uint csize, uint htsize) { int i, j, k; rsc_P ct; void *ctx; char *res; sm_ret_T ret; #if SM_BHTABLE_PERF char buf[1024]; #endif /* SM_BHTABLE_PERF */ ctx = NULL; ct = rsc_new(csize, htsize, create, delete, ctx); SM_TEST(ct != NULL); if (ct == NULL) return; for (i = 0; i < NH; i++) { for (j = 0; j < HLEN; j++) { hashes[i][j] = 'A' + ((i + j) % CHARS); } hashes[i][HLEN - 1] = '\0'; } for (j = 0; j < CSIZE; j++) { i = j % NH; ret = rsc_add(ct, false, hashes[i], KLEN, hashes[VALI(i)], (void **)&res); SM_TEST(!sm_is_err(ret)); SM_TEST(strcmp(res, hashes[VALI(i)]) == 0); cnt = 0; rsc_walk(ct, action, (void *) 0); SM_TEST(cnt == j + 1); k = rsc_usage(ct); SM_TEST(k == (int) ((j + 1) * 100 / CSIZE)); } for (k = CSIZE; k < NH; k++) { res = (char *) rsc_lookup(ct, hashes[k], KLEN); SM_TEST(res == NULL); if (Verbose > 0 && res != NULL) fprintf(stderr, "j=%d, k=%d, res=%s\n", j, k, res); k = rsc_usage(ct); SM_TEST(k == 100); } for (j = 0; j < CSIZE * 3; j++) { i = j % NH; ret = rsc_add(ct, true, hashes[i], KLEN, hashes[VALI(i)], (void **)&res); SM_TEST(!sm_is_err(ret)); SM_TEST(strcmp(res, hashes[VALI(i)]) == 0); cnt = 0; rsc_walk(ct, action, (void *) 0); SM_TEST(cnt == CSIZE); /* make sure that the other entries are not in the cache */ if (j > CSIZE) { for (k = j + 1; k < NH; k++) { res = (char *) rsc_lookup(ct, hashes[k], KLEN); SM_TEST(res == NULL); if (Verbose > 0 && res != NULL) fprintf(stderr, "j=%d, k=%d, res=%s\n", j, k, res); } } k = rsc_usage(ct); SM_TEST(k == 100); } /* XXX need a better test that shows the MRU feature */ #if SM_BHTABLE_PERF if (Verbose > 0) { rsc_stats(ct, buf, sizeof(buf)); printf("%s", buf); } #endif /* SM_BHTABLE_PERF */ rsc_free(ct); } int main(int argc, char *argv[]) { int c; uint csize, htsize; csize = CSIZE; htsize = HTSIZE; while ((c = getopt(argc, argv, "c:h:V")) != -1) { switch (c) { case 'c': csize = (uint) atoi(optarg); break; case 'h': htsize = (uint) atoi(optarg); break; case 'V': ++Verbose; break; default: return(1); } } sm_test_begin(argc, argv, "test rsc 1"); testh(csize, htsize); return sm_test_end(); }