libstdc++: Prefer posix_memalign for aligned-new [PR113258]
[official-gcc.git] / gcc / fibonacci_heap.cc
blob0e93d3ee98bce2c6d141afec86e8f1d4c512cef0
1 /* Fibonacci heap for GNU compiler.
2 Copyright (C) 2016-2024 Free Software Foundation, Inc.
3 Contributed by Martin Liska <mliska@suse.cz>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "alloc-pool.h"
25 #include "fibonacci_heap.h"
26 #include "selftest.h"
28 #if CHECKING_P
30 namespace selftest {
32 /* Selftests. */
34 /* Verify that operations with empty heap work. */
36 typedef fibonacci_node <int, int> int_heap_node_t;
37 typedef fibonacci_heap <int, int> int_heap_t;
39 static void
40 test_empty_heap ()
42 pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
43 int_heap_t *h1 = new int_heap_t (INT_MIN, &allocator);
45 ASSERT_TRUE (h1->empty ());
46 ASSERT_EQ (0, h1->nodes ());
47 ASSERT_EQ (NULL, h1->min ());
49 int_heap_t *h2 = new int_heap_t (INT_MIN, &allocator);
51 int_heap_t *r = h1->union_with (h2);
52 ASSERT_TRUE (r->empty ());
53 ASSERT_EQ (0, r->nodes ());
54 ASSERT_EQ (NULL, r->min ());
56 delete r;
59 #define TEST_HEAP_N 100
60 #define TEST_CALCULATE_VALUE(i) ((3 * i) + 10000)
62 /* Verify heap basic operations. */
64 static void
65 test_basic_heap_operations ()
67 int values[TEST_HEAP_N];
68 int_heap_t *h1 = new int_heap_t (INT_MIN);
70 for (unsigned i = 0; i < TEST_HEAP_N; i++)
72 values[i] = TEST_CALCULATE_VALUE (i);
73 ASSERT_EQ (i, h1->nodes ());
74 h1->insert (i, &values[i]);
75 ASSERT_EQ (0, h1->min_key ());
76 ASSERT_EQ (values[0], *h1->min ());
79 for (unsigned i = 0; i < TEST_HEAP_N; i++)
81 ASSERT_EQ (TEST_HEAP_N - i, h1->nodes ());
82 ASSERT_EQ ((int)i, h1->min_key ());
83 ASSERT_EQ (values[i], *h1->min ());
85 h1->extract_min ();
88 ASSERT_TRUE (h1->empty ());
90 delete h1;
93 /* Builds a simple heap with values in interval 0..TEST_HEAP_N-1, where values
94 of each key is equal to 3 * key + 10000. BUFFER is used as a storage
95 of values and NODES points to inserted nodes. */
97 static int_heap_t *
98 build_simple_heap (int *buffer, int_heap_node_t **nodes)
100 int_heap_t *h = new int_heap_t (INT_MIN);
102 for (unsigned i = 0; i < TEST_HEAP_N; i++)
104 buffer[i] = TEST_CALCULATE_VALUE (i);
105 nodes[i] = h->insert (i, &buffer[i]);
108 return h;
111 /* Verify that fibonacci_heap::replace_key works. */
113 static void
114 test_replace_key ()
116 int values[TEST_HEAP_N];
117 int_heap_node_t *nodes[TEST_HEAP_N];
119 int_heap_t *heap = build_simple_heap (values, nodes);
121 int N = 10;
122 for (unsigned i = 0; i < (unsigned)N; i++)
123 heap->replace_key (nodes[i], 100 * 1000 + i);
125 ASSERT_EQ (TEST_HEAP_N, heap->nodes ());
126 ASSERT_EQ (N, heap->min_key ());
127 ASSERT_EQ (TEST_CALCULATE_VALUE (N), *heap->min ());
129 for (int i = 0; i < TEST_HEAP_N - 1; i++)
130 heap->extract_min ();
132 ASSERT_EQ (1, heap->nodes ());
133 ASSERT_EQ (100 * 1000 + N - 1, heap->min_key ());
135 delete heap;
138 /* Verify that heap can handle duplicate keys. */
140 static void
141 test_duplicate_keys ()
143 int values[3 * TEST_HEAP_N];
144 int_heap_t *heap = new int_heap_t (INT_MIN);
146 for (unsigned i = 0; i < 3 * TEST_HEAP_N; i++)
148 values[i] = TEST_CALCULATE_VALUE (i);
149 heap->insert (i / 3, &values[i]);
152 ASSERT_EQ (3 * TEST_HEAP_N, heap->nodes ());
153 ASSERT_EQ (0, heap->min_key ());
154 ASSERT_EQ (TEST_CALCULATE_VALUE (0), *heap->min ());
156 for (unsigned i = 0; i < 9; i++)
157 heap->extract_min ();
159 for (unsigned i = 0; i < 3; i++)
161 ASSERT_EQ (3, heap->min_key ());
162 heap->extract_min ();
165 delete heap;
168 /* Verify that heap can handle union. */
170 static void
171 test_union ()
173 int value = 777;
174 pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
176 int_heap_t *heap1 = new int_heap_t (INT_MIN, &allocator);
177 for (unsigned i = 0; i < 2 * TEST_HEAP_N; i++)
178 heap1->insert (i, &value);
180 int_heap_t *heap2 = new int_heap_t (INT_MIN, &allocator);
181 for (unsigned i = 2 * TEST_HEAP_N; i < 3 * TEST_HEAP_N; i++)
182 heap2->insert (i, &value);
184 int_heap_t *union_heap = heap1->union_with (heap2);
186 for (int i = 0; i < 3 * TEST_HEAP_N; i++)
188 ASSERT_EQ (i, union_heap->min_key ());
189 union_heap->extract_min ();
192 delete union_heap;
195 /* Verify that heap can handle union with a heap having exactly the same
196 keys. */
198 static void
199 test_union_of_equal_heaps ()
201 int value = 777;
202 pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
204 int_heap_t *heap1 = new int_heap_t (INT_MIN, &allocator);
205 for (unsigned i = 0; i < TEST_HEAP_N; i++)
206 heap1->insert (i, &value);
208 int_heap_t *heap2 = new int_heap_t (INT_MIN, &allocator);
209 for (unsigned i = 0; i < TEST_HEAP_N; i++)
210 heap2->insert (i, &value);
212 int_heap_t *union_heap = heap1->union_with (heap2);
214 for (int i = 0; i < TEST_HEAP_N; i++)
215 for (int j = 0; j < 2; j++)
217 ASSERT_EQ (i, union_heap->min_key ());
218 union_heap->extract_min ();
221 delete union_heap;
224 /* Dummy struct for testing. */
226 class heap_key
228 public:
229 heap_key (int k): key (k)
233 int key;
235 bool operator< (const heap_key &other) const
237 return key > other.key;
240 bool operator== (const heap_key &other) const
242 return key == other.key;
245 bool operator> (const heap_key &other) const
247 return !(*this == other || *this < other);
251 typedef fibonacci_heap<heap_key, int> class_fibonacci_heap_t;
253 /* Verify that heap can handle a struct as key type. */
255 static void
256 test_struct_key ()
258 int value = 123456;
259 class_fibonacci_heap_t *heap = new class_fibonacci_heap_t (INT_MIN);
261 heap->insert (heap_key (1), &value);
262 heap->insert (heap_key (10), &value);
263 heap->insert (heap_key (100), &value);
264 heap->insert (heap_key (1000), &value);
266 ASSERT_EQ (1000, heap->min_key ().key);
267 ASSERT_EQ (4, heap->nodes ());
268 heap->extract_min ();
269 heap->extract_min ();
270 ASSERT_EQ (10, heap->min_key ().key);
271 heap->extract_min ();
272 ASSERT_EQ (&value, heap->min ());
273 heap->extract_min ();
274 ASSERT_TRUE (heap->empty ());
276 delete heap;
279 /* Run all of the selftests within this file. */
281 void
282 fibonacci_heap_cc_tests ()
284 test_empty_heap ();
285 test_basic_heap_operations ();
286 test_replace_key ();
287 test_duplicate_keys ();
288 test_union ();
289 test_union_of_equal_heaps ();
290 test_struct_key ();
293 } // namespace selftest
295 #endif /* #if CHECKING_P */