/*- * Copyright (c) 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. */ #ifndef CRADIX_H #define CRADIX_H #ifdef _KERNEL #include #else #include #include #include #endif #define CRADIX_CHUNK_SIZE 5 #define CRADIX_MAX_FANOUT (1u << CRADIX_CHUNK_SIZE) #define CRADIX_CHUNK_MASK (CRADIX_MAX_FANOUT - 1) #define CRADIX_NCHUNKS \ ((64 + CRADIX_CHUNK_SIZE - 1)/CRADIX_CHUNK_SIZE) typedef uint32_t cradix_bitmap_t; struct cradix_ops; struct cradix { const struct cradix_ops *ops; uintptr_t root; unsigned keylen; }; /* * Should be treated as opaque; used only for alignment and * type-checking. */ struct cradix_node { } __aligned(2); /* Opaque; allocated via the allocator. */ struct cradix_branch; struct cradix_ops { uint64_t (*key)(const struct cradix *, const struct cradix_node *); void * (*alloc)(struct cradix *, size_t); void (*free)(struct cradix *, void *, size_t); void (*recycle)(struct cradix *, void *, size_t); }; void cradix_init(struct cradix *, const struct cradix_ops *); void cradix_destroy(struct cradix *); struct cradix_node * cradix_lookup(const struct cradix *, uint64_t); struct cradix_insert { struct cradix_branch *alloc[CRADIX_CHUNK_SIZE]; struct cradix_branch *recycle; }; bool cradix_insert_begin(struct cradix *, struct cradix_insert *); void cradix_insert_end(struct cradix *, struct cradix_insert *); struct cradix_node * cradix_insert(struct cradix *, struct cradix_node *, struct cradix_insert *); struct cradix_delete { struct cradix_branch *recycle; }; void cradix_delete_begin(struct cradix *, struct cradix_delete *); void cradix_delete_end(struct cradix *, struct cradix_delete *); void cradix_delete(struct cradix *, struct cradix_node *, struct cradix_delete *); struct cradix_node * cradix_delete_key(struct cradix *, uint64_t, struct cradix_delete *); void cradix_dump(const struct cradix *); #endif /* CRADIX_H */