summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-10-18 17:07:38 +0200
committerDavid Robillard <d@drobilla.net>2019-10-18 17:07:56 +0200
commitea4e3d3909be2f0e393362d496a9662591a4e356 (patch)
treefabc8477c37f5660e31b3aa9c77f92e51bcfb20d
parent85512457fbe29aa161417903feaec74f5e7c15c5 (diff)
downloadzix-ea4e3d3909be2f0e393362d496a9662591a4e356.tar.gz
zix-ea4e3d3909be2f0e393362d496a9662591a4e356.tar.bz2
zix-ea4e3d3909be2f0e393362d496a9662591a4e356.zip
Add optional aggressive sorted order check to BTree
-rw-r--r--zix/btree.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/zix/btree.c b/zix/btree.c
index 9990b18..dc8f32b 100644
--- a/zix/btree.c
+++ b/zix/btree.c
@@ -22,6 +22,7 @@
#include <string.h>
// #define ZIX_BTREE_DEBUG 1
+// #define ZIX_BTREE_SORTED_CHECK 1
#ifndef ZIX_BTREE_PAGE_SIZE
# define ZIX_BTREE_PAGE_SIZE 4096
@@ -235,6 +236,30 @@ zix_btree_split_child(ZixBTreeNode* const n,
return rhs;
}
+#ifdef ZIX_BTREE_SORTED_CHECK
+/** Check that `n` is sorted with respect to search key `e`. */
+ZIX_PRIVATE bool
+zix_btree_node_is_sorted_with_respect_to(const ZixBTree* const t,
+ const ZixBTreeNode* const n,
+ const void* const e)
+{
+ if (n->n_vals <= 1) {
+ return true;
+ }
+
+ int cmp = t->cmp(n->vals[0], e, t->cmp_data);
+ for (uint16_t i = 1; i < n->n_vals; ++i) {
+ const int next_cmp = t->cmp(n->vals[i], e, t->cmp_data);
+ if ((cmp >= 0 && next_cmp < 0)) {
+ return false;
+ }
+ cmp = next_cmp;
+ }
+
+ return true;
+}
+#endif
+
/** Find the first value in `n` that is not less than `e` (lower bound). */
ZIX_PRIVATE unsigned
zix_btree_node_find(const ZixBTree* const t,
@@ -242,6 +267,10 @@ zix_btree_node_find(const ZixBTree* const t,
const void* const e,
bool* const equal)
{
+#ifdef ZIX_BTREE_SORTED_CHECK
+ assert(zix_btree_node_is_sorted_with_respect_to(t, n, e));
+#endif
+
unsigned first = 0U;
unsigned len = n->n_vals;
while (len > 0) {