source: mainline/kernel/test/avltree/avltree1.c@ f1380b7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f1380b7 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[358ec13]1/*
2 * Copyright (c) 2007 Vojtech Mencl
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <test.h>
30#include <print.h>
31#include <adt/avl.h>
32#include <debug.h>
[d99c1d2]33#include <typedefs.h>
[358ec13]34
35#define NODE_COUNT 100
36
37static avltree_t avltree;
38
39/*
40 * avl tree nodes in array for faster allocation
41 */
42static avltree_node_t avltree_nodes[NODE_COUNT];
43
[cb01e1e]44/*
[358ec13]45 * head of free nodes' list:
46 */
47static avltree_node_t *first_free_node = NULL;
48
49static int test_tree_balance(avltree_node_t *node);
50static avltree_node_t *test_tree_parents(avltree_node_t *node);
[4a23cb6]51static void print_tree_structure_flat (avltree_node_t *node, int level)
52 __attribute__ ((used));
[358ec13]53static avltree_node_t *alloc_avltree_node(void);
54
55static avltree_node_t *test_tree_parents(avltree_node_t *node)
56{
57 avltree_node_t *tmp;
[a35b458]58
[358ec13]59 if (!node)
60 return NULL;
[a35b458]61
[358ec13]62 if (node->lft) {
63 tmp = test_tree_parents(node->lft);
64 if (tmp != node) {
[cb01e1e]65 TPRINTF("Bad parent pointer key: %" PRIu64
[4a23cb6]66 ", address: %p\n", tmp->key, node->lft);
[358ec13]67 }
68 }
69 if (node->rgt) {
70 tmp = test_tree_parents(node->rgt);
71 if (tmp != node) {
[cb01e1e]72 TPRINTF("Bad parent pointer key: %" PRIu64
[4a23cb6]73 ", address: %p\n",
[358ec13]74 tmp->key,node->rgt);
75 }
76 }
77 return node->par;
78}
79
80int test_tree_balance(avltree_node_t *node)
81{
82 int h1, h2, diff;
[a35b458]83
[358ec13]84 if (!node)
85 return 0;
[a35b458]86
[358ec13]87 h1 = test_tree_balance(node->lft);
88 h2 = test_tree_balance(node->rgt);
89 diff = h2 - h1;
[a35b458]90
[cb01e1e]91 if ((diff != node->balance) || ((diff != -1) && (diff != 0) && (diff != 1)))
92 TPRINTF("Bad balance\n");
[a35b458]93
[cb01e1e]94 return ((h1 > h2) ? (h1 + 1) : (h2 + 1));
[358ec13]95}
96
97/**
98 * Prints the structure of the node, which is level levels from the top of the
[cb01e1e]99 * tree.
[358ec13]100 */
[cb01e1e]101static void print_tree_structure_flat(avltree_node_t *node, int level)
[358ec13]102{
103 /*
104 * You can set the maximum level as high as you like.
[cb01e1e]105 * Most of the time, you'll want to debug code using small trees,
106 * so that a large level indicates a loop, which is a bug.
[358ec13]107 */
108 if (level > 16) {
[cb01e1e]109 TPRINTF("[...]");
[358ec13]110 return;
111 }
[a35b458]112
[358ec13]113 if (node == NULL)
114 return;
[a35b458]115
[cb01e1e]116 TPRINTF("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance);
[358ec13]117 if (node->lft != NULL || node->rgt != NULL) {
[cb01e1e]118 TPRINTF("(");
[a35b458]119
[358ec13]120 print_tree_structure_flat(node->lft, level + 1);
121 if (node->rgt != NULL) {
[cb01e1e]122 TPRINTF(",");
[358ec13]123 print_tree_structure_flat(node->rgt, level + 1);
124 }
[a35b458]125
[cb01e1e]126 TPRINTF(")");
[358ec13]127 }
128}
129
130static void alloc_avltree_node_prepare(void)
131{
132 int i;
[a35b458]133
[cb01e1e]134 for (i = 0; i < NODE_COUNT - 1; i++)
[358ec13]135 avltree_nodes[i].par = &avltree_nodes[i + 1];
[a35b458]136
[4a23cb6]137 avltree_nodes[i].par = NULL;
[a35b458]138
[358ec13]139 /*
140 * Node keys which will be used for insertion. Up to NODE_COUNT size of
141 * array.
142 */
[a35b458]143
[358ec13]144 /* First tree node and same key */
145 avltree_nodes[0].key = 60;
146 avltree_nodes[1].key = 60;
147 avltree_nodes[2].key = 60;
[a35b458]148
[358ec13]149 /* LL rotation */
150 avltree_nodes[3].key = 50;
151 avltree_nodes[4].key = 40;
152 avltree_nodes[5].key = 30;
[a35b458]153
[358ec13]154 /* LR rotation */
155 avltree_nodes[6].key = 20;
156 avltree_nodes[7].key = 20;
157 avltree_nodes[8].key = 25;
158 avltree_nodes[9].key = 25;
[a35b458]159
[358ec13]160 /* LL rotation in lower floor */
161 avltree_nodes[10].key = 35;
[a35b458]162
[358ec13]163 /* RR rotation */
164 avltree_nodes[11].key = 70;
165 avltree_nodes[12].key = 80;
[a35b458]166
[358ec13]167 /* RL rotation */
168 avltree_nodes[13].key = 90;
169 avltree_nodes[14].key = 85;
[a35b458]170
[358ec13]171 /* Insert 0 key */
172 avltree_nodes[15].key = 0;
173 avltree_nodes[16].key = 0;
[a35b458]174
[358ec13]175 /* Insert reverse */
176 avltree_nodes[17].key = 600;
177 avltree_nodes[18].key = 500;
178 avltree_nodes[19].key = 400;
179 avltree_nodes[20].key = 300;
[a35b458]180
[358ec13]181 for (i = 21; i < NODE_COUNT; i++)
182 avltree_nodes[i].key = i * 3;
[a35b458]183
[358ec13]184 first_free_node = &avltree_nodes[0];
185}
186
187static avltree_node_t *alloc_avltree_node(void)
188{
189 avltree_node_t *node;
[a35b458]190
[358ec13]191 node = first_free_node;
192 first_free_node = first_free_node->par;
[a35b458]193
[358ec13]194 return node;
195}
196
[98000fb]197static void test_tree_insert(avltree_t *tree, size_t node_count)
[358ec13]198{
199 unsigned int i;
200 avltree_node_t *newnode;
[a35b458]201
[358ec13]202 avltree_create(tree);
[a35b458]203
[7e752b2]204 TPRINTF("Inserting %zu nodes...", node_count);
[a35b458]205
[358ec13]206 for (i = 0; i < node_count; i++) {
207 newnode = alloc_avltree_node();
[a35b458]208
[358ec13]209 avltree_insert(tree, newnode);
[cb01e1e]210 test_tree_parents(tree->root);
211 test_tree_balance(tree->root);
[358ec13]212 }
[a35b458]213
[cb01e1e]214 TPRINTF("done.\n");
[358ec13]215}
216
[98000fb]217static void test_tree_delete(avltree_t *tree, size_t node_count,
[cb01e1e]218 int node_position)
[358ec13]219{
220 avltree_node_t *delnode;
221 unsigned int i;
[a35b458]222
[358ec13]223 switch (node_position) {
224 case 0:
[cb01e1e]225 TPRINTF("Deleting root nodes...");
[a35b458]226
[358ec13]227 while (tree->root != NULL) {
228 delnode = tree->root;
229 avltree_delete(tree, delnode);
[cb01e1e]230 test_tree_parents(tree->root);
231 test_tree_balance(tree->root);
232 }
[358ec13]233 break;
234 case 1:
[cb01e1e]235 TPRINTF("Deleting nodes according to creation time...");
[a35b458]236
[358ec13]237 for (i = 0; i < node_count; i++) {
238 avltree_delete(tree, &avltree_nodes[i]);
[cb01e1e]239 test_tree_parents(tree->root);
240 test_tree_balance(tree->root);
[358ec13]241 }
[cb01e1e]242 break;
[358ec13]243 }
[a35b458]244
[cb01e1e]245 TPRINTF("done.\n");
[358ec13]246}
247
[98000fb]248static void test_tree_delmin(avltree_t *tree, size_t node_count)
[358ec13]249{
[6c441cf8]250 unsigned int i = 0;
[a35b458]251
[cb01e1e]252 TPRINTF("Deleting minimum nodes...");
[a35b458]253
[358ec13]254 while (tree->root != NULL) {
255 i++;
256 avltree_delete_min(tree);
[cb01e1e]257 test_tree_parents(tree->root);
258 test_tree_balance(tree->root);
[358ec13]259 }
[a35b458]260
[cb01e1e]261 if (i != node_count)
262 TPRINTF("Bad node count. Some nodes have been lost!\n");
[a35b458]263
[cb01e1e]264 TPRINTF("done.\n");
[358ec13]265}
266
[a000878c]267const char *test_avltree1(void)
[358ec13]268{
269 alloc_avltree_node_prepare();
[cb01e1e]270 test_tree_insert(&avltree, NODE_COUNT);
271 test_tree_delete(&avltree, NODE_COUNT, 0);
[a35b458]272
[358ec13]273 alloc_avltree_node_prepare();
[cb01e1e]274 test_tree_insert(&avltree, NODE_COUNT);
275 test_tree_delete(&avltree, NODE_COUNT, 1);
[a35b458]276
[358ec13]277 alloc_avltree_node_prepare();
[cb01e1e]278 test_tree_insert(&avltree, NODE_COUNT);
279 test_tree_delmin(&avltree, NODE_COUNT);
[a35b458]280
[358ec13]281 return NULL;
282}
Note: See TracBrowser for help on using the repository browser.