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 : */