LCOV - code coverage report
Current view: top level - data/source/set - data_visible_set.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 92 110 83.6 %
Date: 2024-10-26 21:44:38 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* File: data_visible_set.c; Copyright and License: see below */
       2             : 
       3             : #include "set/data_visible_set.h"
       4             : #include "u8/u8_trace.h"
       5             : #include <stdio.h>
       6             : #include <stdlib.h>
       7             : #include <assert.h>
       8             : 
       9          16 : void data_visible_set_init( data_visible_set_t *this_ )
      10             : {
      11          16 :     U8_TRACE_BEGIN();
      12          16 :     U8_TRACE_INFO_INT( "sizeof(data_visible_set_t):", sizeof(data_visible_set_t) );
      13             : 
      14          16 :     data_diagram_init_empty( &((*this_).diagram) );
      15          16 :     (*this_).visible_classifier_count = 0;
      16          16 :     (*this_).feature_count = 0;
      17          16 :     (*this_).relationship_count = 0;
      18             : 
      19          16 :     U8_TRACE_END();
      20          16 : }
      21             : 
      22           1 : void data_visible_set_reinit( data_visible_set_t *this_ )
      23             : {
      24           1 :     U8_TRACE_BEGIN();
      25             : 
      26           1 :     data_diagram_reinit_empty( &((*this_).diagram) );
      27           1 :     data_visible_set_private_destroy_visible_classifiers( this_ );
      28           1 :     data_visible_set_private_destroy_features( this_ );
      29           1 :     data_visible_set_private_destroy_relationships( this_ );
      30             : 
      31           1 :     U8_TRACE_END();
      32             : 
      33           1 : }
      34             : 
      35           6 : void data_visible_set_destroy( data_visible_set_t *this_ )
      36             : {
      37           6 :     U8_TRACE_BEGIN();
      38             : 
      39           6 :     data_diagram_destroy( &((*this_).diagram) );
      40           6 :     data_visible_set_private_destroy_visible_classifiers( this_ );
      41           6 :     data_visible_set_private_destroy_features( this_ );
      42           6 :     data_visible_set_private_destroy_relationships( this_ );
      43             : 
      44           6 :     U8_TRACE_END();
      45           6 : }
      46             : 
      47           6 : u8_error_t data_visible_set_load( data_visible_set_t *this_, data_row_id_t diagram_id, data_database_reader_t *db_reader )
      48             : {
      49           6 :     U8_TRACE_BEGIN();
      50           6 :     assert( NULL != db_reader );
      51           6 :     u8_error_t result = U8_ERROR_NONE;
      52             : 
      53           6 :     if ( DATA_ROW_ID_VOID == diagram_id )
      54             :     {
      55             :         /* re-init */
      56           0 :         data_diagram_reinit_empty( &((*this_).diagram) );
      57             : 
      58           0 :         data_visible_set_private_destroy_visible_classifiers( this_ );
      59           0 :         data_visible_set_private_destroy_features( this_ );
      60           0 :         data_visible_set_private_destroy_relationships( this_ );
      61             :     }
      62             :     else
      63             :     {
      64             :         u8_error_t db_err;
      65             : 
      66           6 :         data_diagram_destroy( &((*this_).diagram) );
      67           6 :         data_visible_set_private_destroy_visible_classifiers( this_ );
      68           6 :         data_visible_set_private_destroy_features( this_ );
      69           6 :         data_visible_set_private_destroy_relationships( this_ );
      70             : 
      71             :         /* load diagram */
      72           6 :         db_err = data_database_reader_get_diagram_by_id ( db_reader, diagram_id, &((*this_).diagram) );
      73             : 
      74           6 :         if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
      75             :         {
      76           0 :             U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading a diagram" );
      77             :         }
      78           6 :         if ( u8_error_contains( db_err, U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
      79             :         {
      80           0 :             U8_LOG_ERROR( "U8_ERROR_ARRAY_BUFFER_EXCEEDED at loading a diagram" );
      81             :         }
      82           6 :         if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED|U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
      83             :         {
      84             :             /* error at loading */
      85           1 :             data_diagram_reinit_empty( &((*this_).diagram) );
      86             :         }
      87           6 :         result |= db_err;  /* collect error flags */
      88             : 
      89             :         /* load classifiers */
      90           6 :         db_err = data_database_reader_get_classifiers_by_diagram_id ( db_reader,
      91             :                                                                       diagram_id,
      92             :                                                                       DATA_VISIBLE_SET_MAX_CLASSIFIERS,
      93           6 :                                                                       &((*this_).visible_classifiers),
      94             :                                                                       &((*this_).visible_classifier_count)
      95             :                                                                     );
      96             : 
      97           6 :         if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
      98             :         {
      99           0 :             U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading visible classifiers of a diagram" );
     100             :         }
     101           6 :         if ( u8_error_contains( db_err, U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     102             :         {
     103           1 :             U8_LOG_ERROR( "U8_ERROR_ARRAY_BUFFER_EXCEEDED at loading visible classifiers of a diagram" );
     104             :         }
     105           6 :         if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED|U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     106             :         {
     107             :             /* error at loading */
     108           0 :             (*this_).visible_classifier_count = 0;
     109             :         }
     110           6 :         result |= db_err;  /* collect error flags */
     111             : 
     112             :         /* load features */
     113           6 :         db_err = data_database_reader_get_features_by_diagram_id ( db_reader,
     114             :                                                                    diagram_id,
     115             :                                                                    DATA_VISIBLE_SET_MAX_FEATURES,
     116           6 :                                                                    &((*this_).features),
     117             :                                                                    &((*this_).feature_count)
     118             :                                                                  );
     119             : 
     120           6 :         if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     121             :         {
     122           0 :             U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading features of a diagram" );
     123             :         }
     124           6 :         if ( u8_error_contains( db_err, U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     125             :         {
     126           1 :             U8_LOG_ERROR( "U8_ERROR_ARRAY_BUFFER_EXCEEDED at loading features of a diagram" );
     127             :         }
     128           6 :         if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED|U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     129             :         {
     130             :             /* error at loading */
     131           0 :             (*this_).feature_count = 0;
     132             :         }
     133           6 :         result |= db_err;  /* collect error flags */
     134             : 
     135             :         /* load relationships */
     136           6 :         db_err = data_database_reader_get_relationships_by_diagram_id ( db_reader,
     137             :                                                                         diagram_id,
     138             :                                                                         DATA_VISIBLE_SET_MAX_RELATIONSHIPS,
     139           6 :                                                                         &((*this_).relationships),
     140             :                                                                         &((*this_).relationship_count)
     141             :                                                                       );
     142             : 
     143           6 :         if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     144             :         {
     145           0 :             U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading relationships of a diagram" );
     146             :         }
     147           6 :         if ( u8_error_contains( db_err, U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     148             :         {
     149           1 :             U8_LOG_ERROR( "U8_ERROR_ARRAY_BUFFER_EXCEEDED at loading relationships of a diagram" );
     150             :         }
     151           6 :         if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED|U8_ERROR_ARRAY_BUFFER_EXCEEDED ) )
     152             :         {
     153             :             /* error at loading */
     154           0 :             (*this_).relationship_count = 0;
     155             :         }
     156           6 :         result |= db_err;  /* collect error flags */
     157             :     }
     158             : 
     159             :     /* update the containment cache */
     160           6 :     data_visible_set_update_containment_cache( this_ );
     161             : 
     162           6 :     U8_TRACE_END_ERR(result);
     163           6 :     return result;
     164             : }
     165             : 
     166          16 : void data_visible_set_update_containment_cache ( data_visible_set_t *this_ )
     167             : {
     168          16 :     U8_TRACE_BEGIN();
     169          16 :     assert( (*this_).relationship_count <= DATA_VISIBLE_SET_MAX_RELATIONSHIPS );
     170          16 :     assert( (*this_).visible_classifier_count <= DATA_VISIBLE_SET_MAX_CLASSIFIERS );
     171             : 
     172             :     /* reset the containment array */
     173          16 :     memset( &((*this_).containment_cache), '\0', sizeof( (*this_).containment_cache ) );
     174             : 
     175             :     static const int MAX_SEARCH_PASSES = 4;  /* with 4 passes, we can find ancesters and decendants which are related via 2*4=8 links and more */
     176          16 :     bool new_containments_found = true;
     177             : 
     178          32 :     for ( int pass = 0; ( pass < MAX_SEARCH_PASSES ) && new_containments_found; pass ++ )
     179             :     {
     180          16 :         new_containments_found = false;
     181             : 
     182        7222 :         for ( uint32_t rel_idx = 0; rel_idx < (*this_).relationship_count; rel_idx ++ )
     183             :         {
     184             :             data_relationship_t *the_relationship;
     185        7206 :             the_relationship = &((*this_).relationships[rel_idx]);
     186             : 
     187             :             data_relationship_type_t the_type;
     188        7206 :             the_type = data_relationship_get_main_type ( the_relationship );
     189             : 
     190        7206 :             if ( DATA_RELATIONSHIP_TYPE_UML_CONTAINMENT == the_type )
     191             :             {
     192             :                 data_row_id_t parent_id;
     193             :                 data_row_id_t child_id;
     194        1025 :                 parent_id = data_relationship_get_from_classifier_row_id ( the_relationship );
     195        1025 :                 child_id = data_relationship_get_to_classifier_row_id ( the_relationship );
     196             :                 int32_t parent_index;
     197             :                 int32_t child_index;
     198        1025 :                 parent_index = data_visible_set_get_classifier_index ( this_, parent_id );
     199        1025 :                 child_index = data_visible_set_get_classifier_index ( this_, child_id );
     200        1025 :                 if ( ( parent_index != -1 )&&( child_index != -1 ) )
     201             :                 {
     202        1025 :                     assert ( 0 <= parent_index );
     203        1025 :                     assert ( parent_index < (*this_).visible_classifier_count );
     204        1025 :                     assert ( 0 <= child_index );
     205        1025 :                     assert ( child_index < (*this_).visible_classifier_count );
     206             : 
     207             :                     /* add the current relation to the containment_cache */
     208        1025 :                     (*this_).containment_cache[parent_index][child_index] = true;
     209             : 
     210             :                     /* all ancestors of parent are ancestors of child */
     211      132099 :                     for ( uint32_t ancestor_index = 0; ancestor_index < (*this_).visible_classifier_count; ancestor_index ++ )
     212             :                     {
     213      131074 :                         if ( (*this_).containment_cache[ancestor_index][parent_index] )
     214             :                         {
     215           0 :                             if ( ! (*this_).containment_cache[ancestor_index][child_index] )
     216             :                             {
     217           0 :                                 new_containments_found = true;
     218           0 :                                 (*this_).containment_cache[ancestor_index][child_index] = true;
     219             :                             }
     220             :                         }
     221             :                     }
     222             : 
     223             :                     /* all descendants of child are descendants of parent */
     224      132099 :                     for ( uint32_t descendant_index = 0; descendant_index < (*this_).visible_classifier_count; descendant_index ++ )
     225             :                     {
     226      131074 :                         if ( (*this_).containment_cache[child_index][descendant_index] )
     227             :                         {
     228           0 :                             if ( ! (*this_).containment_cache[parent_index][descendant_index] )
     229             :                             {
     230           0 :                                 new_containments_found = true;
     231           0 :                                 (*this_).containment_cache[parent_index][descendant_index] = true;
     232             :                             }
     233             :                         }
     234             :                     }
     235             : 
     236             :                 }
     237             :                 /* else relation points outside the set of classifiers visible in current diagram */
     238             :             }
     239             :         }
     240             :     }
     241             : 
     242          16 :     U8_TRACE_END();
     243          16 : }
     244             : 
     245             : 
     246             : /*
     247             : Copyright 2016-2024 Andreas Warnke
     248             : 
     249             : Licensed under the Apache License, Version 2.0 (the "License");
     250             : you may not use this file except in compliance with the License.
     251             : You may obtain a copy of the License at
     252             : 
     253             :     http://www.apache.org/licenses/LICENSE-2.0
     254             : 
     255             : Unless required by applicable law or agreed to in writing, software
     256             : distributed under the License is distributed on an "AS IS" BASIS,
     257             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     258             : See the License for the specific language governing permissions and
     259             : limitations under the License.
     260             : */

Generated by: LCOV version 1.16