From 1f9de04ae408b9645f3fe1adfdbca1c7b121698c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 10 Oct 2019 15:51:44 +1030 Subject: [PATCH] ccan: import updated version to get uintmap_before(). Signed-off-by: Rusty Russell --- ccan/README | 2 +- ccan/ccan/intmap/intmap.c | 57 +++++++++++++++++++++ ccan/ccan/intmap/intmap.h | 35 +++++++++++++ ccan/ccan/intmap/test/run-order-smallsize.c | 23 ++++++++- ccan/ccan/intmap/test/run-order.c | 25 +++++++++ ccan/ccan/rbuf/test/run-partial-read.c | 2 +- ccan/ccan/rbuf/test/run-term-eof.c | 6 +-- ccan/ccan/rbuf/test/run.c | 4 +- 8 files changed, 146 insertions(+), 8 deletions(-) diff --git a/ccan/README b/ccan/README index ae497dc61..cfd522c97 100644 --- a/ccan/README +++ b/ccan/README @@ -1,3 +1,3 @@ CCAN imported from http://ccodearchive.net. -CCAN version: init-2486-g46cfc3ad +CCAN version: init-2488-g7aac849a diff --git a/ccan/ccan/intmap/intmap.c b/ccan/ccan/intmap/intmap.c index 3473ef323..341b8a921 100644 --- a/ccan/ccan/intmap/intmap.c +++ b/ccan/ccan/intmap/intmap.c @@ -231,6 +231,63 @@ none_left: return NULL; } +void *intmap_before_(const struct intmap *map, intmap_index_t *indexp) +{ + const struct intmap *n, *prev = NULL; + intmap_index_t index = (*indexp) - 1; + + /* Special case of overflow */ + if (index == (intmap_index_t)-1ULL) + goto none_left; + + /* Special case of empty map */ + if (intmap_empty_(map)) + goto none_left; + + /* Follow down, until prefix differs. */ + n = map; + while (!n->v) { + int crit = critbit(n); + u8 direction; + intmap_index_t prefix, idx; + + idx = (index >> crit); + direction = idx & 1; + + /* Leave critbit in place: we can't shift by 64 anyway */ + idx |= 1; + prefix = n->u.n->prefix_and_critbit >> crit; + + /* If this entire tree is less than index, take last */ + if (idx > prefix) + return intmap_last_(n, indexp); + /* If this entire tree is greater than index, we're past it. */ + else if (idx < prefix) + goto try_lesser_tree; + + /* Remember lesser tree for backtracking */ + if (direction) + prev = n; + n = &n->u.n->child[direction]; + } + + /* Found a predecessor? */ + if (n->u.i <= index) { + errno = 0; + *indexp = n->u.i; + return n->v; + } + +try_lesser_tree: + /* If we ever took a lesser branch, go back to lesser branch */ + if (prev) + return intmap_last_(&prev->u.n->child[0], indexp); + +none_left: + errno = ENOENT; + return NULL; +} + void *intmap_last_(const struct intmap *map, intmap_index_t *indexp) { const struct intmap *n; diff --git a/ccan/ccan/intmap/intmap.h b/ccan/ccan/intmap/intmap.h index 207b7c9d2..834c969fa 100644 --- a/ccan/ccan/intmap/intmap.h +++ b/ccan/ccan/intmap/intmap.h @@ -309,6 +309,32 @@ void *intmap_after_(const struct intmap *map, intmap_index_t *indexp); tcon_cast((smap), sintmap_canary, \ sintmap_after_(sintmap_unwrap_(smap), (indexp))) +/** + * uintmap_before - get the closest preceding index in an unsigned intmap + * @umap: the typed intmap to iterate through. + * @indexp: the succeeding index (may not exist) + * + * Returns NULL if the there is no entry < @indexp, otherwise + * populates *@indexp and returns the highest entry < @indexp. + */ +#define uintmap_before(umap, indexp) \ + tcon_cast((umap), uintmap_canary, \ + intmap_before_(uintmap_unwrap_(umap), (indexp))) + +void *intmap_before_(const struct intmap *map, intmap_index_t *indexp); + +/** + * sintmap_before - get the closest preceding index in a signed intmap + * @smap: the typed intmap to iterate through. + * @indexp: the succeeding index (may not exist) + * + * Returns NULL if the there is no entry < @indexp, otherwise + * populates *@indexp and returns the highest entry < @indexp. + */ +#define sintmap_before(smap, indexp) \ + tcon_cast((smap), sintmap_canary, \ + sintmap_before_(sintmap_unwrap_(smap), (indexp))) + /** * uintmap_last - get last value in an unsigned intmap * @umap: the typed intmap to iterate through. @@ -455,6 +481,15 @@ static inline void *sintmap_after_(const struct intmap *map, return ret; } +static inline void *sintmap_before_(const struct intmap *map, + sintmap_index_t *indexp) +{ + intmap_index_t i = SINTMAP_OFF(*indexp); + void *ret = intmap_before_(map, &i); + *indexp = SINTMAP_UNOFF(i); + return ret; +} + static inline void *sintmap_last_(const struct intmap *map, sintmap_index_t *indexp) { diff --git a/ccan/ccan/intmap/test/run-order-smallsize.c b/ccan/ccan/intmap/test/run-order-smallsize.c index 63c5b9c9f..8121f2769 100644 --- a/ccan/ccan/intmap/test/run-order-smallsize.c +++ b/ccan/ccan/intmap/test/run-order-smallsize.c @@ -19,6 +19,15 @@ static bool check_umap(const umap *map) bool last = true; /* Must be in order, must contain value. */ + prev = 256; + for (v = uintmap_last(map, &i); v; v = uintmap_before(map, &i)) { + if (i >= prev) + return false; + if (*v != i) + return false; + prev = i; + } + prev = -1; for (v = uintmap_first(map, &i); v; v = uintmap_after(map, &i)) { if (i <= prev) @@ -40,6 +49,15 @@ static bool check_smap(const smap *map) bool last = true; /* Must be in order, must contain value. */ + prev = 0x80000000ULL; + for (v = sintmap_last(map, &i); v; v = sintmap_before(map, &i)) { + if (i >= prev) + return false; + if (*v != i) + return false; + prev = i; + } + prev = -0x80000001ULL; for (v = sintmap_first(map, &i); v; v = sintmap_after(map, &i)) { if (i <= prev) @@ -52,7 +70,7 @@ static bool check_smap(const smap *map) return last; } -int main(void) +int main(int argc, char *argv[]) { umap umap; smap smap; @@ -64,6 +82,9 @@ int main(void) uintmap_init(&umap); sintmap_init(&smap); + if (argc > 1) + srandom(atoi(argv[1])); + for (i = 0; i < NUM; i++) { urandoms[i] = random(); srandoms[i] = random(); diff --git a/ccan/ccan/intmap/test/run-order.c b/ccan/ccan/intmap/test/run-order.c index f7e86692a..d945a4a86 100644 --- a/ccan/ccan/intmap/test/run-order.c +++ b/ccan/ccan/intmap/test/run-order.c @@ -36,6 +36,19 @@ static bool check_umap(const umap *map) last = (uintmap_last(map, &last_idx) == v); } + if (!last) + return false; + + prev = INT_MAX; + for (v = uintmap_last(map, &i); v; v = uintmap_before(map, &i)) { + if ((int64_t)i >= prev) + return false; + if (*v != i) + return false; + prev = i; + last = (uintmap_first(map, &last_idx) == v); + } + if (!last) return false; @@ -71,6 +84,18 @@ static bool check_smap(const smap *map) prev = i; } + if (!last) + return false; + + prev = 0x80000001ULL; + for (v = sintmap_last(map, &i); v; v = sintmap_before(map, &i)) { + if (i >= prev) + return false; + if (*v != i) + return false; + prev = i; + last = (sintmap_first(map, &last_idx) == v); + } if (!last) return false; diff --git a/ccan/ccan/rbuf/test/run-partial-read.c b/ccan/ccan/rbuf/test/run-partial-read.c index 7ecf79d35..8b5d90186 100644 --- a/ccan/ccan/rbuf/test/run-partial-read.c +++ b/ccan/ccan/rbuf/test/run-partial-read.c @@ -31,7 +31,7 @@ int main(void) /* Grab ourselves for comparison. */ buf[full_read(fd, buf, sizeof(buf))] = '\0'; - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); for (i = 0, p = buf; *p; i++) { lines[i] = p; diff --git a/ccan/ccan/rbuf/test/run-term-eof.c b/ccan/ccan/rbuf/test/run-term-eof.c index 86d7c18d4..0c346d7ea 100644 --- a/ccan/ccan/rbuf/test/run-term-eof.c +++ b/ccan/ccan/rbuf/test/run-term-eof.c @@ -27,7 +27,7 @@ int main(void) /* Grab ourselves for comparison. */ len = read(fd, buf, sizeof(buf)); buf[len] = '\0'; - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); /* We have exact-size buffer, which causes problems adding term. */ rbuf_init(&in, fd, malloc(len), len, test_realloc); @@ -44,7 +44,7 @@ int main(void) free(rbuf_cleanup(&in)); /* Try again. */ - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); rbuf_init(&in, fd, malloc(len), len, test_realloc); p = rbuf_read_str(&in, 64); ok1(p); @@ -53,7 +53,7 @@ int main(void) free(rbuf_cleanup(&in)); /* Normal case, we get rbuf_start after nul */ - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); rbuf_init(&in, fd, NULL, 0, test_realloc); p = rbuf_read_str(&in, '^'); ok1(p); diff --git a/ccan/ccan/rbuf/test/run.c b/ccan/ccan/rbuf/test/run.c index 593ef2708..0f0e7d290 100644 --- a/ccan/ccan/rbuf/test/run.c +++ b/ccan/ccan/rbuf/test/run.c @@ -28,7 +28,7 @@ int main(void) /* Grab ourselves for comparison. */ len = read(fd, buf, sizeof(buf)); buf[len] = '\0'; - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); for (i = 0, p = buf; *p; i++) { lines[i] = p; @@ -62,7 +62,7 @@ int main(void) free(rbuf_cleanup(&in)); /* Another way of reading the entire (text) file. */ - lseek(fd, SEEK_SET, 0); + lseek(fd, 0, SEEK_SET); rbuf_init(&in, fd, NULL, 0, test_realloc); p = rbuf_read_str(&in, 0); ok1(p);