1 /* Fibonacci heap for GNU compiler.
2 Copyright (C) 2016-2021 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
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
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/>. */
23 #include "coretypes.h"
24 #include "alloc-pool.h"
25 #include "fibonacci_heap.h"
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
;
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 ());
59 #define TEST_HEAP_N 100
60 #define TEST_CALCULATE_VALUE(i) ((3 * i) + 10000)
62 /* Verify heap basic operations. */
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 ());
88 ASSERT_TRUE (h1
->empty ());
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. */
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
]);
111 /* Verify that fibonacci_heap::replace_key works. */
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
);
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 ());
138 /* Verify that heap can handle duplicate keys. */
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 ();
168 /* Verify that heap can handle union. */
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 ();
195 /* Verify that heap can handle union with a heap having exactly the same
199 test_union_of_equal_heaps ()
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 ();
224 /* Dummy struct for testing. */
229 heap_key (int k
): key (k
)
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. */
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 ());
279 /* Run all of the selftests within this file. */
282 fibonacci_heap_c_tests ()
285 test_basic_heap_operations ();
287 test_duplicate_keys ();
289 test_union_of_equal_heaps ();
293 } // namespace selftest
295 #endif /* #if CHECKING_P */