Graphviz 14.1.2~dev.20260118.1035
Loading...
Searching...
No Matches
node.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "config.h"
12
13#include <stdlib.h>
14#include <inttypes.h>
15#include <label/index.h>
16#include <stdbool.h>
17#include <stddef.h>
18#include <stdint.h>
19#include <stdio.h>
20#include <assert.h>
21#include <label/node.h>
22#include <util/alloc.h>
23
24/* Make a new node and initialize to have all branch cells empty.
25*/
27 Node_t *n = gv_alloc(sizeof(Node_t));
28 InitNode(n);
29 return n;
30}
31
32/* Initialize a Node structure.
33*/
35{
36 n->count = 0;
37 n->level = -1;
38 for (size_t i = 0; i < NODECARD; i++)
39 InitBranch(&(n->branch[i]));
40}
41
42/* Initialize one branch cell in a node.
43*/
45{
46 InitRect(&(b->rect));
47 b->child = NULL;
48}
49
50#ifdef RTDEBUG
51/* Print out the data in a node.
52*/
53void PrintNode(Node_t * n)
54{
55 assert(n);
56
57 fprintf(stderr, "node");
58 if (n->level == 0)
59 fprintf(stderr, " LEAF");
60 else if (n->level > 0)
61 fprintf(stderr, " NONLEAF");
62 else
63 fprintf(stderr, " TYPE=?");
64 fprintf(stderr, " level=%d count=%d child address=%p\n",
65 n->level, n->count, n);
66
67 for (size_t i = 0; i < NODECARD; i++) {
68 if (n->branch[i].child != NULL)
69 PrintBranch(i, &n->branch[i]);
70 }
71}
72
73void PrintBranch(int i, Branch_t * b)
74{
75 fprintf(stderr, " child[%d] X%X\n", i, (unsigned int) b->child);
76 PrintRect(b->rect);
77}
78#endif
79
80/* Find the smallest rectangle that includes all rectangles in
81** branches of a node.
82*/
84{
85 Rect_t r;
86 assert(n);
87
88 InitRect(&r);
89 bool flag = true;
90 for (size_t i = 0; i < NODECARD; i++)
91 if (n->branch[i].child) {
92 if (flag) {
93 r = n->branch[i].rect;
94 flag = false;
95 } else
96 r = CombineRect(r, n->branch[i].rect);
97 }
98 return r;
99}
100
101/* Pick a branch. Pick the one that will need the smallest increase
102** in area to accommodate the new rectangle. This will result in the
103** least total area for the covering rectangles in the current node.
104** In case of a tie, pick the one which was smaller before, to get
105** the best resolution when searching.
106*/
108 uint64_t bestIncr = 0;
109 uint64_t bestArea = 0;
110 int best=0;
111 bool bestSet = false;
112 assert(n);
113
114 for (int i = 0; i < NODECARD; i++) {
115 if (n->branch[i].child) {
116 const Rect_t rr = n->branch[i].rect;
117 uint64_t area = RectArea(rr);
118 Rect_t rect = CombineRect(r, rr);
119 uint64_t increase = RectArea(rect) - area;
120 if (!bestSet || increase < bestIncr) {
121 best = i;
122 bestArea = area;
123 bestIncr = increase;
124 bestSet = true;
125 } else if (increase == bestIncr && area < bestArea) {
126 best = i;
127 bestArea = area;
128 bestIncr = increase;
129 }
130# ifdef RTDEBUG
131 fprintf(stderr,
132 "i=%d area before=%" PRIu64 " area after=%" PRIu64 " increase=%" PRIu64
133 "\n", i, area, area + increase, increase);
134# endif
135 }
136 }
137# ifdef RTDEBUG
138 fprintf(stderr, "\tpicked %d\n", best);
139# endif
140 return best;
141}
142
143/* Add a branch to a node. Split the node if necessary.
144** Returns 0 if node not split. Old node updated.
145** Returns 1 if node split, sets *new to address of new node.
146** Old node updated, becomes one of two.
147*/
148int AddBranch(RTree_t * rtp, Branch_t * b, Node_t * n, Node_t ** new)
149{
150 assert(b);
151 assert(n);
152
153 if (n->count < NODECARD) { /* split won't be necessary */
154 size_t i;
155 for (i = 0; i < NODECARD; i++) { /* find empty branch */
156 if (n->branch[i].child == NULL) {
157 n->branch[i] = *b;
158 n->count++;
159 break;
160 }
161 }
162 assert(i < NODECARD);
163 return 0;
164 } else {
165 assert(new);
166 SplitNode(rtp, n, b, new);
167 return 1;
168 }
169}
170
171/* Disconnect a dependent node.
172*/
173void DisconBranch(Node_t * n, int i)
174{
175 assert(n && i >= 0 && i < NODECARD);
176 assert(n->branch[i].child);
177
178 InitBranch(&(n->branch[i]));
179 n->count--;
180}
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
Definition alloc.h:47
node NULL
Definition grammar.y:181
#define NODECARD
Definition index.h:43
void InitNode(Node_t *n)
Definition node.c:34
Node_t * RTreeNewNode(void)
Definition node.c:26
int AddBranch(RTree_t *rtp, Branch_t *b, Node_t *n, Node_t **new)
Definition node.c:148
Rect_t NodeCover(Node_t *n)
Definition node.c:83
void InitBranch(Branch_t *b)
Definition node.c:44
void DisconBranch(Node_t *n, int i)
Definition node.c:173
int PickBranch(Rect_t r, Node_t *n)
Definition node.c:107
void PrintBranch(int, Branch_t *)
void InitRect(Rect_t *r)
Definition rectangle.c:30
Rect_t CombineRect(const Rect_t r, const Rect_t rr)
Definition rectangle.c:84
uint64_t RectArea(const Rect_t r)
Definition rectangle.c:64
void SplitNode(RTree_t *rtp, Node_t *n, Branch_t *b, Node_t **nn)
Definition split.q.c:36
Definition node.h:19
Rect_t rect
Definition node.h:20
struct Node * child
Definition node.h:21
Definition node.h:24
int level
Definition node.h:26
struct Branch branch[NODECARD]
Definition node.h:27
int count
Definition node.h:25
Definition index.h:65