/*
* 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-2.c,v 1.16 2005/05/31 21:00:28 ca Exp $")
#include <stdio.h>
#include "sm/memops.h"
#include "sm/assert.h"
#include "sm/rpool.h"
#include "sm/rsc.h"
#include "sm/error.h"
#include "sm/test.h"
#define CSIZE 13
#define HTSIZE 25
#define CHARS 64
#define NH 61 /* must be less than CHARS */
#define HLEN 12
#define KLEN (HLEN - 2)
static int Verbose = 0;
static int deleted = 0;
static char hashes[NH][HLEN];
static void *
create(const char *key, uint len, void *value, void *ctx)
{
char *n;
sm_rpool_P rpool;
rpool = (sm_rpool_P) ctx;
n = sm_rpool_strdup(rpool, value);
if (Verbose > 1)
fprintf(stderr, "create(%s)=%s\n", key, n == NULL ? "<NULL>" : n);
return n;
}
static sm_ret_T
delete(void *data, void *ctx)
{
sm_rpool_P rpool;
rpool = (sm_rpool_P) ctx;
if (Verbose > 1)
fprintf(stderr, "delete(%s)\n", (char *)data);
sm_rpool_free(rpool, data);
++deleted;
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;
/* prepare hashes[] */
for (i = 0; i < NH; i++)
{
for (j = 0; j < HLEN; j++)
{
hashes[i][j] = 'A' + ((i + j) % CHARS);
}
hashes[i][HLEN - 1] = '\0';
}
/* fill rsc */
for (j = 0; j < CSIZE; j++)
{
i = j % NH;
ret = rsc_add(ct, false, hashes[i], KLEN, hashes[i], (void **)&res);
SM_TEST(!sm_is_err(ret));
SM_TEST(strcmp(res, hashes[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));
}
/* make sure nothing else is in rsc */
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);
}
/* rm from rsc */
for (j = 0; j < CSIZE; j++)
{
i = j % NH;
ret = rsc_rm(ct, hashes[i], KLEN);
SM_TEST(sm_is_success(ret));
cnt = 0;
rsc_walk(ct, action, (void *) 0);
SM_TEST(cnt == CSIZE - (j + 1));
}
k = 0;
for (j = 0; j < NH; j++)
{
i = j % NH;
deleted = 0;
ret = rsc_add(ct, true, hashes[i], KLEN, hashes[i], (void **)&res);
SM_TEST(!sm_is_err(ret));
SM_TEST(strcmp(res, hashes[i]) == 0);
SM_TEST(deleted == 0);
if (j > CSIZE / 2)
{
ret = rsc_rm(ct, hashes[k], KLEN);
SM_TEST(sm_is_success(ret));
k = (k + 1) % NH;
}
}
#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 2");
testh(csize, htsize);
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1