YetAnotherCoupler 3.2.0_a
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#include <stdlib.h>
6
7#include "ensure_array_size.h"
8#include "interval_tree.h"
9#include "utils_core.h"
10
11static int
13{
14 return (a->range.left > b->range.left) - (a->range.left < b->range.left);
15}
16
17static double
18tree_part(struct interval_node intervals[], size_t num_nodes)
19{
20 size_t med = num_nodes / 2;
21 double max = intervals[med].range.right;
22 if (med)
23 {
24 double right;
25 if ((right = tree_part(intervals, med)) > max)
26 max = right;
27 }
28 if (med + 1 < num_nodes)
29 {
30 double right;
31 if ((right = tree_part(intervals + med + 1, num_nodes - med - 1)) > max)
32 max = right;
33 }
34 intervals[med].max = max;
35 return max;
36}
37
38void
39yac_generate_interval_tree(struct interval_node intervals[], size_t num_nodes)
40{
41 qsort(intervals, num_nodes, sizeof(intervals[0]),
42 (int(*)(const void *, const void*))iv_compar);
43 tree_part(intervals, num_nodes);
44}
45
46static inline void
47overlap_push(struct overlaps *overlaps, size_t idx)
48{
49 size_t i = overlaps->num_overlaps;
51 overlaps->overlap_iv[i] = idx;
53}
54
55static void
56search_interval_tree_(struct interval_node tree[], size_t num_nodes,
57 struct interval query, struct overlaps *overlaps,
58 size_t ofs)
59{
60 /* while x is non-empty sub-trees */
61 if (num_nodes)
62 {
63 size_t x = num_nodes/2;
64 if (overlap_test(tree[x].range, query))
65 overlap_push(overlaps, x + ofs);
66 if (x && tree[x/2].max >= query.left)
67 search_interval_tree_(tree, x, query, overlaps, ofs);
68 if (x < num_nodes - 1
69 && tree[x].range.left <= query.right
70 && tree[x + 1 + (num_nodes - x - 1)/2].max >= query.left)
71 search_interval_tree_(tree + x + 1, num_nodes - x - 1, query, overlaps,
72 ofs + x + 1);
73 }
74}
75
76void
77yac_search_interval_tree(struct interval_node tree[], size_t num_nodes,
78 struct interval query, struct overlaps *overlaps)
79{
80 search_interval_tree_(tree, num_nodes, query, overlaps, 0);
81}
82
83
#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