LCOV - code coverage report
Current view: top level - gcc - fibonacci_heap.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 98.5 % 131 129
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Fibonacci heap for GNU compiler.
       2              :    Copyright (C) 2016-2026 Free Software Foundation, Inc.
       3              :    Contributed by Martin Liska <mliska@suse.cz>
       4              : 
       5              : This file is part of GCC.
       6              : 
       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.
      11              : 
      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.
      16              : 
      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/>.  */
      20              : 
      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"
      27              : 
      28              : #if CHECKING_P
      29              : 
      30              : namespace selftest {
      31              : 
      32              : /* Selftests.  */
      33              : 
      34              : /* Verify that operations with empty heap work.  */
      35              : 
      36              : typedef fibonacci_node <int, int> int_heap_node_t;
      37              : typedef fibonacci_heap <int, int> int_heap_t;
      38              : 
      39              : static void
      40            4 : test_empty_heap ()
      41              : {
      42            4 :   pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
      43            4 :   int_heap_t *h1 = new int_heap_t (INT_MIN, &allocator);
      44              : 
      45            4 :   ASSERT_TRUE (h1->empty ());
      46            4 :   ASSERT_EQ (0, h1->nodes ());
      47            4 :   ASSERT_EQ (NULL, h1->min ());
      48              : 
      49            4 :   int_heap_t *h2 = new int_heap_t (INT_MIN, &allocator);
      50              : 
      51            4 :   int_heap_t *r = h1->union_with (h2);
      52            4 :   ASSERT_TRUE (r->empty ());
      53            4 :   ASSERT_EQ (0, r->nodes ());
      54            4 :   ASSERT_EQ (NULL, r->min ());
      55              : 
      56            4 :   delete r;
      57            4 : }
      58              : 
      59              : #define TEST_HEAP_N 100
      60              : #define TEST_CALCULATE_VALUE(i)  ((3 * i) + 10000)
      61              : 
      62              : /* Verify heap basic operations.  */
      63              : 
      64              : static void
      65            4 : test_basic_heap_operations ()
      66              : {
      67            4 :   int values[TEST_HEAP_N];
      68            4 :   int_heap_t *h1 = new int_heap_t (INT_MIN);
      69              : 
      70          404 :   for (unsigned i = 0; i < TEST_HEAP_N; i++)
      71              :     {
      72          400 :       values[i] = TEST_CALCULATE_VALUE (i);
      73          400 :       ASSERT_EQ (i, h1->nodes ());
      74          400 :       h1->insert (i, &values[i]);
      75          400 :       ASSERT_EQ (0, h1->min_key ());
      76          800 :       ASSERT_EQ (values[0], *h1->min ());
      77              :     }
      78              : 
      79          404 :   for (unsigned i = 0; i < TEST_HEAP_N; i++)
      80              :     {
      81          400 :       ASSERT_EQ (TEST_HEAP_N - i, h1->nodes ());
      82          400 :       ASSERT_EQ ((int)i, h1->min_key ());
      83          800 :       ASSERT_EQ (values[i], *h1->min ());
      84              : 
      85          400 :       h1->extract_min ();
      86              :     }
      87              : 
      88            4 :   ASSERT_TRUE (h1->empty ());
      89              : 
      90            4 :   delete h1;
      91            4 : }
      92              : 
      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.  */
      96              : 
      97              : static int_heap_t *
      98            4 : build_simple_heap (int *buffer, int_heap_node_t **nodes)
      99              : {
     100            4 :   int_heap_t *h = new int_heap_t (INT_MIN);
     101              : 
     102          404 :   for (unsigned i = 0; i < TEST_HEAP_N; i++)
     103              :     {
     104          400 :       buffer[i] = TEST_CALCULATE_VALUE (i);
     105          400 :       nodes[i] = h->insert (i, &buffer[i]);
     106              :     }
     107              : 
     108            4 :   return h;
     109              : }
     110              : 
     111              : /* Verify that fibonacci_heap::replace_key works.  */
     112              : 
     113              : static void
     114            4 : test_replace_key ()
     115              : {
     116            4 :   int values[TEST_HEAP_N];
     117            4 :   int_heap_node_t *nodes[TEST_HEAP_N];
     118              : 
     119            4 :   int_heap_t *heap = build_simple_heap (values, nodes);
     120              : 
     121            4 :   int N = 10;
     122           44 :   for (unsigned i = 0; i < (unsigned)N; i++)
     123           40 :     heap->replace_key (nodes[i], 100 * 1000 + i);
     124              : 
     125            4 :   ASSERT_EQ (TEST_HEAP_N, heap->nodes ());
     126            4 :   ASSERT_EQ (N, heap->min_key ());
     127            8 :   ASSERT_EQ (TEST_CALCULATE_VALUE (N), *heap->min ());
     128              : 
     129          400 :   for (int i = 0; i < TEST_HEAP_N - 1; i++)
     130          396 :     heap->extract_min ();
     131              : 
     132            4 :   ASSERT_EQ (1, heap->nodes ());
     133            4 :   ASSERT_EQ (100 * 1000 + N - 1, heap->min_key ());
     134              : 
     135            4 :   delete heap;
     136            4 : }
     137              : 
     138              : /* Verify that heap can handle duplicate keys.  */
     139              : 
     140              : static void
     141            4 : test_duplicate_keys ()
     142              : {
     143            4 :   int values[3 * TEST_HEAP_N];
     144            4 :   int_heap_t *heap = new int_heap_t (INT_MIN);
     145              : 
     146         1204 :   for (unsigned i = 0; i < 3 * TEST_HEAP_N; i++)
     147              :     {
     148         1200 :       values[i] = TEST_CALCULATE_VALUE (i);
     149         1200 :       heap->insert (i / 3, &values[i]);
     150              :     }
     151              : 
     152            4 :   ASSERT_EQ (3 * TEST_HEAP_N, heap->nodes ());
     153            4 :   ASSERT_EQ (0, heap->min_key ());
     154            8 :   ASSERT_EQ (TEST_CALCULATE_VALUE (0), *heap->min ());
     155              : 
     156           40 :   for (unsigned i = 0; i < 9; i++)
     157           36 :     heap->extract_min ();
     158              : 
     159           16 :   for (unsigned i = 0; i < 3; i++)
     160              :     {
     161           12 :       ASSERT_EQ (3, heap->min_key ());
     162           12 :       heap->extract_min ();
     163              :     }
     164              : 
     165            4 :   delete heap;
     166            4 : }
     167              : 
     168              : /* Verify that heap can handle union.  */
     169              : 
     170              : static void
     171            4 : test_union ()
     172              : {
     173            4 :   int value = 777;
     174            4 :   pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
     175              : 
     176            4 :   int_heap_t *heap1 = new int_heap_t (INT_MIN, &allocator);
     177          804 :   for (unsigned i = 0; i < 2 * TEST_HEAP_N; i++)
     178          800 :     heap1->insert (i, &value);
     179              : 
     180            4 :   int_heap_t *heap2 = new int_heap_t (INT_MIN, &allocator);
     181          404 :   for (unsigned i = 2 * TEST_HEAP_N; i < 3 * TEST_HEAP_N; i++)
     182          400 :     heap2->insert (i, &value);
     183              : 
     184            4 :   int_heap_t *union_heap = heap1->union_with (heap2);
     185              : 
     186         1204 :   for (int i = 0; i < 3 * TEST_HEAP_N; i++)
     187              :     {
     188         1200 :       ASSERT_EQ (i, union_heap->min_key ());
     189         1200 :       union_heap->extract_min ();
     190              :     }
     191              : 
     192            4 :   delete union_heap;
     193            4 : }
     194              : 
     195              : /* Verify that heap can handle union with a heap having exactly the same
     196              :    keys.  */
     197              : 
     198              : static void
     199            4 : test_union_of_equal_heaps ()
     200              : {
     201            4 :   int value = 777;
     202            4 :   pool_allocator allocator ("fibheap test", sizeof (int_heap_node_t));
     203              : 
     204            4 :   int_heap_t *heap1 = new int_heap_t (INT_MIN, &allocator);
     205          404 :   for (unsigned i = 0; i < TEST_HEAP_N; i++)
     206          400 :     heap1->insert (i, &value);
     207              : 
     208            4 :   int_heap_t *heap2 = new int_heap_t (INT_MIN, &allocator);
     209          404 :   for (unsigned i = 0; i < TEST_HEAP_N; i++)
     210          400 :     heap2->insert (i, &value);
     211              : 
     212            4 :   int_heap_t *union_heap = heap1->union_with (heap2);
     213              : 
     214          404 :   for (int i = 0; i < TEST_HEAP_N; i++)
     215         1200 :     for (int j = 0; j < 2; j++)
     216              :     {
     217          800 :       ASSERT_EQ (i, union_heap->min_key ());
     218          800 :       union_heap->extract_min ();
     219              :     }
     220              : 
     221            4 :   delete union_heap;
     222            4 : }
     223              : 
     224              : /* Dummy struct for testing.  */
     225              : 
     226              : class heap_key
     227              : {
     228              : public:
     229           20 :   heap_key (int k): key (k)
     230              :   {
     231              :   }
     232              : 
     233              :   int key;
     234              : 
     235           20 :   bool operator< (const heap_key &other) const
     236              :   {
     237           20 :     return key > other.key;
     238              :   }
     239              : 
     240              :   bool operator== (const heap_key &other) const
     241              :   {
     242              :     return key == other.key;
     243              :   }
     244              : 
     245            0 :   bool operator> (const heap_key &other) const
     246              :   {
     247            0 :     return !(*this == other || *this < other);
     248              :   }
     249              : };
     250              : 
     251              : typedef fibonacci_heap<heap_key, int> class_fibonacci_heap_t;
     252              : 
     253              : /* Verify that heap can handle a struct as key type.  */
     254              : 
     255              : static void
     256            4 : test_struct_key ()
     257              : {
     258            4 :   int value = 123456;
     259            4 :   class_fibonacci_heap_t *heap = new class_fibonacci_heap_t (INT_MIN);
     260              : 
     261            4 :   heap->insert (heap_key (1), &value);
     262            4 :   heap->insert (heap_key (10), &value);
     263            4 :   heap->insert (heap_key (100), &value);
     264            4 :   heap->insert (heap_key (1000), &value);
     265              : 
     266            4 :   ASSERT_EQ (1000, heap->min_key ().key);
     267            4 :   ASSERT_EQ (4, heap->nodes ());
     268            4 :   heap->extract_min ();
     269            4 :   heap->extract_min ();
     270            4 :   ASSERT_EQ (10, heap->min_key ().key);
     271            4 :   heap->extract_min ();
     272            4 :   ASSERT_EQ (&value, heap->min ());
     273            4 :   heap->extract_min ();
     274            4 :   ASSERT_TRUE (heap->empty ());
     275              : 
     276            4 :   delete heap;
     277            4 : }
     278              : 
     279              : /* Run all of the selftests within this file.  */
     280              : 
     281              : void
     282            4 : fibonacci_heap_cc_tests ()
     283              : {
     284            4 :   test_empty_heap ();
     285            4 :   test_basic_heap_operations ();
     286            4 :   test_replace_key ();
     287            4 :   test_duplicate_keys ();
     288            4 :   test_union ();
     289            4 :   test_union_of_equal_heaps ();
     290            4 :   test_struct_key ();
     291            4 : }
     292              : 
     293              : } // namespace selftest
     294              : 
     295              : #endif /* #if CHECKING_P */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.