skip to content
==> include/mesh/jobs/ranges.h <==
1/* @ajax/mesh-jobs-ranges: a set of u64 items (a job's items) as disjoint, non-touching half-open
2 * ranges [s, e), in order. An endless range ends at UINT64_MAX. jobs.rs's `Ranges`.
3 *
4 * Kept as a sorted array of pairs; a zeroed mj_ranges is the empty set. */
5#ifndef MESH_JOBS_RANGES_H
6#define MESH_JOBS_RANGES_H
7
8#include "mesh/strbuf.h"
9
10#include <stdbool.h>
11#include <stddef.h>
12#include <stdint.h>
13
14typedef struct {
15    uint64_t (*v)[2]; /* [start, end) */
16    size_t n, cap;
17} mj_ranges;
18
19mj_ranges mj_ranges_of(uint64_t s, uint64_t e);
20void mj_ranges_free(mj_ranges *r);
21mj_ranges mj_ranges_clone(const mj_ranges *r);
22void mj_ranges_clear(mj_ranges *r);
23bool mj_ranges_eq(const mj_ranges *a, const mj_ranges *b);
24
25static inline bool mj_ranges_is_empty(const mj_ranges *r) { return r->n == 0; }
26/* Items in the set (saturating: an endless range is ~UINT64_MAX). */
27uint64_t mj_ranges_len(const mj_ranges *r);
28/* Ranges in the set. */
29static inline size_t mj_ranges_count(const mj_ranges *r) { return r->n; }
30/* The first item; false when empty. */
31bool mj_ranges_first(const mj_ranges *r, uint64_t *x);
32/* The end of the last range; false when empty. */
33bool mj_ranges_end(const mj_ranges *r, uint64_t *e);
34bool mj_ranges_contains(const mj_ranges *r, uint64_t x);
35
36void mj_ranges_insert(mj_ranges *r, uint64_t s, uint64_t e);
37void mj_ranges_add(mj_ranges *r, uint64_t x);
38void mj_ranges_union(mj_ranges *r, const mj_ranges *o);
39/* Removes [s, e); true if anything was in it. */
40bool mj_ranges_remove(mj_ranges *r, uint64_t s, uint64_t e);
41bool mj_ranges_take(mj_ranges *r, uint64_t x);
42void mj_ranges_subtract(mj_ranges *r, const mj_ranges *o);
43/* The items of both. */
44mj_ranges mj_ranges_intersect(const mj_ranges *a, const mj_ranges *b);
45/* Takes up to n items from the front. */
46mj_ranges mj_ranges_take_front(mj_ranges *r, uint64_t n);
47/* The item with k items of the set before it; false when there are fewer than k + 1. */
48bool mj_ranges_nth(const mj_ranges *r, uint64_t k, uint64_t *x);
49
50/* `a-b,c-d` (half-open; `a-` is endless), `-` when empty. */
51void mj_ranges_word(const mj_ranges *r, msb *out);
52char *mj_ranges_word_new(const mj_ranges *r);
53/* The `word` form, or items `a`, `a-b`, `a-` (endless) comma-separated. On error returns false
54 * with *err (the caller frees it). */
55bool mj_ranges_parse(const char *s, mj_ranges *out, char **err);
56
57#endif