/*- * Copyright (c) 2015--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 CRITBIT_H #define CRITBIT_H #ifdef _KERNEL #include #else /* !_KERNEL */ #include #include #endif /* _KERNEL */ struct critbit; struct critbit_node; struct critbit_ops { const void *(*cbo_key)(const struct critbit *, const struct critbit_node *, size_t *); void (*cbo_membar_producer)(void); void (*cbo_membar_datadep_consumer)(void); struct critbit_branch * (*cbo_branch_alloc)(struct critbit *); void (*cbo_branch_free)(struct critbit *, struct critbit_branch *); }; struct critbit { uintptr_t cb_root; const struct critbit_ops *cb_ops; }; struct critbit_branch { uintptr_t cbb_child[2]; uint16_t cbb_idx; uint16_t cbb_bits; }; /* Needed only for alignment. */ struct critbit_node { } __aligned(2); #define CRITBIT_MAX_KEYLEN 65535 void critbit_init(struct critbit *, const struct critbit_ops *); void critbit_destroy(struct critbit *); void critbit_node_init(struct critbit_node *, const void *, size_t); void critbit_node_destroy(struct critbit_node *); struct critbit_branch * critbit_branch_alloc(struct critbit *); void critbit_branch_free(struct critbit *, struct critbit_branch *); bool critbit_empty(const struct critbit *); struct critbit_node * critbit_lookup(const struct critbit *, const void *, size_t); struct critbit_node * critbit_min(const struct critbit *); struct critbit_node * critbit_max(const struct critbit *); struct critbit_node * critbit_min_prefix(const struct critbit *, const void *, size_t); struct critbit_node * critbit_max_prefix(const struct critbit *, const void *, size_t); struct critbit_node * critbit_insert(struct critbit *, struct critbit_node *); struct critbit_node * critbit_insert_explicit(struct critbit *, struct critbit_node *, struct critbit_branch **); void critbit_delete(struct critbit *, struct critbit_node *); void critbit_delete_explicit(struct critbit *, struct critbit_node *, struct critbit_branch **); struct critbit_node * critbit_delete_key(struct critbit *, const void *, size_t); struct critbit_node * critbit_delete_key_explicit(struct critbit *, const void *, size_t, struct critbit_branch **); struct critbit_iter { struct critbit *cbi_critbit; uintptr_t cbi_root; unsigned char *cbi_stack; /* dir_{8i+j} is 1 & (stack[i] >> j) */ unsigned cbi_stacklen; unsigned cbi_depth; /* number of bits down the stack */ }; void critbit_iter_init(struct critbit *, struct critbit_iter *, void *, size_t); void critbit_iter_destroy(struct critbit *, struct critbit_iter *); struct critbit_node * critbit_iter_min(struct critbit *, struct critbit_iter *); struct critbit_node * critbit_iter_max(struct critbit *, struct critbit_iter *); struct critbit_node * critbit_iter_min_prefix(struct critbit *, struct critbit_iter *, const void *, size_t); struct critbit_node * critbit_iter_max_prefix(struct critbit *, struct critbit_iter *, const void *, size_t); struct critbit_node * critbit_iter_next(struct critbit *, struct critbit_iter *); struct critbit_node * critbit_iter_prev(struct critbit *, struct critbit_iter *); void critbit_check(struct critbit *); void critbit_print(struct critbit *); #endif /* CRITBIT_H */