/*- * Copyright (c) 2016--2019 Taylor R. Campbell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include "critbit.h" #define arraycount(A) (sizeof(A)/sizeof(A[0])) const struct { const char *p; unsigned n; } S[] = { {"FOO", 3}, {"bar", 3}, {"baz", 3}, {"baz\0", 4}, {"foo", 3}, }; struct critbit_node N[arraycount(S)]; const size_t n = arraycount(S); const size_t insperm[arraycount(S)] = {0,3,4,2,1}; const size_t delperm[arraycount(S)] = {0,1,3,2,4}; char iterstack[42]; struct critbit_txn_delete_1 txnd1[arraycount(S)]; struct critbit_txn_delete txnd; static const void * getkey(const struct critbit *C __unused, const struct critbit_node *n, size_t *keylenp) { *keylenp = S[n - N].n; return S[n - N].p; } static void membar_none(void) { } static void null_sync(struct critbit *C __unused) { } static const struct critbit_ops ops = { .cbo_key = getkey, .cbo_membar_producer = membar_none, .cbo_membar_datadep_consumer = membar_none, .cbo_sync = null_sync, }; int main(int argc, char **argv) { struct critbit C; size_t i; (void)argc; /* ignore */ (void)argv; /* ignore */ critbit_init(&C, &ops); critbit_check(&C); assert(critbit_empty(&C)); for (i = 0; i < n; i++) { critbit_node_init(&N[i], S[i].p, S[i].n); critbit_check(&C); } for (i = 0; i < n; i++) { const size_t j = insperm[i]; struct critbit_node *cn = critbit_insert(&C, &N[j]); (void)printf("inserted %p (%p): %s (%u)\n", cn, &N[j], S[j].p, S[j].n); assert(cn == &N[j]); critbit_check(&C); assert(!critbit_empty(&C)); } for (i = 0; i < n; i++) { const char *k = S[i].p; struct critbit_node *cn = critbit_lookup(&C, k, S[i].n); (void)printf("lookedup %p (%p): %s (%u)\n", cn, &N[i], S[i].p, S[i].n); assert(cn == &N[i]); critbit_check(&C); } (void)printf("first prefix `ba': %p\n", critbit_min_prefix(&C, "ba", 2)); (void)printf("last prefix `ba': %p\n", critbit_max_prefix(&C, "ba", 2)); critbit_print(&C); { struct critbit_iter I; struct critbit_node *cn; critbit_iter_init(&C, &I, iterstack, sizeof iterstack); (void)printf("forward\n"); for (i = 0, cn = critbit_iter_min(&C, &I); i < arraycount(S) && cn != NULL; i++, cn = critbit_iter_next(&C, &I)) { assert(cn == &N[i]); (void)printf("iter %p: %s (%u)\n", cn, S[cn - N].p, S[cn - N].n); } assert(i == arraycount(S)); (void)printf("backward\n"); for (i = arraycount(S), cn = critbit_iter_max(&C, &I); cn != NULL && i --> 0; cn = critbit_iter_prev(&C, &I)) { assert(cn == &N[i]); (void)printf("iter %p: %s (%u)\n", cn, S[cn - N].p, S[cn - N].n); } assert(i == 0); assert(cn == NULL); (void)printf("forward starting with `b'\n"); for (i = 1, cn = critbit_iter_min_prefix(&C, &I, "b", 1); i < 4 && cn != NULL; i++, cn = critbit_iter_next(&C, &I)) { assert(cn == &N[i]); (void)printf("iter %p: %s (%u)\n", cn, S[cn - N].p, S[cn - N].n); } assert(i == 4); assert(cn == NULL); (void)printf("backward starting with `b'\n"); for (i = 4, cn = critbit_iter_max_prefix(&C, &I, "b", 1); cn != NULL && i --> 0; cn = critbit_iter_prev(&C, &I)) { (void)printf("iter %p: %s (%u)\n", cn, S[cn - N].p, S[cn - N].n); } assert(i == 1); assert(cn == NULL); (void)printf("done\n"); critbit_iter_destroy(&C, &I); } critbit_txn_delete_begin(&C, &txnd, txnd1, n); for (i = 0; i < arraycount(delperm); i++) { size_t j = delperm[i]; const char *k = S[j].p; struct critbit_node *cn = critbit_txn_delete_key(&C, k, S[j].n, &txnd); (void)printf("deleted %p (%p): %s (%u)\n", cn, &N[j], S[j].p, S[j].n); assert(cn == &N[j]); critbit_print(&C); fflush(stdout); for (j = 0; j < n; j++) { const char *k = S[j].p; struct critbit_node *cn = critbit_lookup(&C, k, S[j].n); (void)printf("lookedup %p (%p): %s\n", cn, &N[j], k ? k : "(null)"); assert(cn == &N[j] || cn == NULL); } printf("check\n"); critbit_print(&C); fflush(stdout); critbit_check(&C); } critbit_txn_delete_commit(&C, &txnd); for (i = 0; i < n; i++) { critbit_node_destroy(&N[i]); critbit_check(&C); } assert(critbit_empty(&C)); critbit_destroy(&C); return 0; }