YAC 3.18.0
Yet Another Coupler
Loading...
Searching...
No Matches
interval_tree.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5
6#include "ensure_array_size.h"
7#include "interval_tree.h"
8#include "utils_core.h"
9
10static int
12{
13 return (a->range.left > b->range.left) - (a->range.left < b->range.left);
14}
15
16static double
17tree_part(struct interval_node intervals[], size_t num_nodes)
18{
19 size_t med = num_nodes / 2;
20 double max = intervals[med].range.right;
21 if (med)
22 {
23 double right;
24 if ((right = tree_part(intervals, med)) > max)
25 max = right;
26 }
27 if (med + 1 < num_nodes)
28 {
29 double right;
30 if ((right = tree_part(intervals + med + 1, num_nodes - med - 1)) > max)
31 max = right;
32 }
33 intervals[med].max = max;
34 return max;
35}
36
37void
38yac_generate_interval_tree(struct interval_node intervals[], size_t num_nodes)
39{
40 qsort(intervals, num_nodes, sizeof(intervals[0]),
41 (int(*)(const void *, const void*))iv_compar);
42 tree_part(intervals, num_nodes);
43}
44
45static inline void
46overlap_push(struct overlaps *overlaps, size_t idx)
47{
48 size_t i = overlaps->num_overlaps;
50 overlaps->overlap_iv[i] = idx;
52}
53
54static void
55search_interval_tree_(struct interval_node tree[], size_t num_nodes,
56 struct interval query, struct overlaps *overlaps,
57 size_t ofs)
58{
59 /* while x is non-empty sub-trees */
60 if (num_nodes)
61 {
62 size_t x = num_nodes/2;
63 if (overlap_test(tree[x].range, query))
64 overlap_push(overlaps, x + ofs);
65 if (x && tree[x/2].max >= query.left)
66 search_interval_tree_(tree, x, query, overlaps, ofs);
67 if (x < num_nodes - 1
68 && tree[x].range.left <= query.right
69 && tree[x + 1 + (num_nodes - x - 1)/2].max >= query.left)
70 search_interval_tree_(tree + x + 1, num_nodes - x - 1, query, overlaps,
71 ofs + x + 1);
72 }
73}
74
75void
76yac_search_interval_tree(struct interval_node tree[], size_t num_nodes,
77 struct interval query, struct overlaps *overlaps)
78{
79 search_interval_tree_(tree, num_nodes, query, overlaps, 0);
80}
81
82
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
static void overlap_push(struct overlaps *overlaps, size_t idx)
static void search_interval_tree_(struct interval_node tree[], size_t num_nodes, struct interval query, struct overlaps *overlaps, size_t ofs)
static double tree_part(struct interval_node intervals[], size_t num_nodes)
void yac_search_interval_tree(struct interval_node tree[], size_t num_nodes, struct interval query, struct overlaps *overlaps)
static int iv_compar(struct interval_node *a, struct interval_node *b)
void yac_generate_interval_tree(struct interval_node intervals[], size_t num_nodes)
static int overlap_test(struct interval a, struct interval b)
struct interval range
double right
double left
size_t * overlap_iv
size_t num_overlaps
size_t a_size