* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.114.4.13 2011/11/07 01:20:51 marka Exp $ */
+/* $Id: check.c,v 1.114.4.14 2011/11/30 04:26:22 each Exp $ */
/*! \file */
* Check that all zone statements are syntactically correct and
* there are no duplicate zones.
*/
- tresult = isc_symtab_create(mctx, 100, freekey, mctx,
+ tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
ISC_FALSE, &symtab);
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
* Check that all key statements are syntactically correct and
* there are no duplicate keys.
*/
- tresult = isc_symtab_create(mctx, 100, freekey, mctx,
+ tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
ISC_FALSE, &symtab);
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: symtab.c,v 1.30 2007/06/19 23:47:17 tbox Exp $ */
+/* $Id: symtab.c,v 1.30.558.1 2011/11/30 04:26:22 each Exp $ */
/*! \file */
unsigned int magic;
isc_mem_t * mctx;
unsigned int size;
+ unsigned int count;
+ unsigned int maxload;
eltlist_t * table;
isc_symtabaction_t undefine_action;
void * undefine_arg;
INIT_LIST(symtab->table[i]);
symtab->mctx = mctx;
symtab->size = size;
+ symtab->count = 0;
+ symtab->maxload = size * 3 / 4;
symtab->undefine_action = undefine_action;
symtab->undefine_arg = undefine_arg;
symtab->case_sensitive = case_sensitive;
return (ISC_R_SUCCESS);
}
+static void
+grow_table(isc_symtab_t *symtab) {
+ eltlist_t *newtable;
+ unsigned int i, newsize, newmax;
+
+ REQUIRE(symtab != NULL);
+
+ newsize = symtab->size * 2;
+ newmax = newsize * 3 / 4;
+
+ newtable = isc_mem_get(symtab->mctx, newsize * sizeof(eltlist_t));
+ if (newtable == NULL)
+ return;
+
+ for (i = 0; i < newsize; i++)
+ INIT_LIST(newtable[i]);
+
+ for (i = 0; i < symtab->size; i++) {
+ elt_t *elt, *nelt;
+
+ for (elt = HEAD(symtab->table[i]); elt != NULL; elt = nelt) {
+ nelt = NEXT(elt, link);
+ unsigned int hv;
+
+ UNLINK(symtab->table[i], elt, link);
+ hv = hash(elt->key, symtab->case_sensitive);
+ APPEND(newtable[hv % newsize], elt, link);
+ }
+ }
+
+ isc_mem_put(symtab->mctx, symtab->table,
+ symtab->size * sizeof(eltlist_t));
+
+ symtab->table = newtable;
+ symtab->size = newsize;
+ symtab->maxload = newmax;
+}
+
isc_result_t
isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
isc_symvalue_t value, isc_symexists_t exists_policy)
if (elt == NULL)
return (ISC_R_NOMEMORY);
ISC_LINK_INIT(elt, link);
+ symtab->count++;
}
/*
*/
PREPEND(symtab->table[bucket], elt, link);
+ if (symtab->count > symtab->maxload)
+ grow_table(symtab);
+
return (ISC_R_SUCCESS);
}
elt->value, symtab->undefine_arg);
UNLINK(symtab->table[bucket], elt, link);
isc_mem_put(symtab->mctx, elt, sizeof(*elt));
+ symtab->count--;
return (ISC_R_SUCCESS);
}
--- /dev/null
+/*
+ * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: symtab_test.c,v 1.1.6.2 2011/11/30 04:26:23 each Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/symtab.h>
+
+#include "isctest.h"
+
+static void
+undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
+ UNUSED(arg);
+
+ ATF_REQUIRE_EQ(type, 1);
+ isc_mem_free(mctx, key);
+ isc_mem_free(mctx, value.as_pointer);
+}
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(symtab_grow);
+ATF_TC_HEAD(symtab_grow, tc) {
+ atf_tc_set_md_var(tc, "descr", "symbol table growth");
+}
+ATF_TC_BODY(symtab_grow, tc) {
+ isc_result_t result;
+ isc_symtab_t *st = NULL;
+ isc_symvalue_t value;
+ isc_symexists_t policy = isc_symexists_reject;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_symtab_create(mctx, 3, undefine, NULL, ISC_FALSE, &st);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(st != NULL);
+
+ /* Nothing should be in the table yet */
+
+ /*
+ * Put 1024 entries in the table (this should necessate
+ * regrowing the hash table several times
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS)
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Try to put them in again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_EXISTS);
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Retrieve them; this should succeed
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, value.as_pointer);
+ }
+
+ /*
+ * Undefine them
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_undefine(st, str, 1);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ }
+
+ /*
+ * Retrieve them again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
+ }
+
+ isc_symtab_destroy(&st);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, symtab_grow);
+
+ return (atf_no_error());
+}
+