1 /*---------------------------------------------------------------------------* 2 * srec_tokens.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #include"srec.h" 21 #include"srec_tokens.h" 22 #include "passert.h" 23 #include "portable.h" 24 25 26 /* we do no expect dump_core() to ever be called */ 27 static void dump_core(char *msg) 28 { 29 PLogError ( msg ); 30 ASSERT(0); 31 } 32 33 /* 34 * fsmarc_token management 35 */ 36 37 int count_fsmarc_token_list(srec* rec, stokenID token_index) 38 { 39 int count = 0; 40 41 while (token_index != MAXstokenID) 42 { 43 fsmarc_token* stoken = &rec->fsmarc_token_array[token_index]; 44 token_index = stoken->next_token_index; 45 count++; 46 ASSERT(count < 5000); 47 } 48 return count; 49 } 50 51 /* static int num_fsmarc_tokens_allocated = 0; */ 52 53 void initialize_free_fsmarc_tokens(srec *rec) 54 { 55 stokenID i; 56 57 /* num_fsmarc_tokens_allocated = 0; */ 58 for (i = 0;i < rec->fsmarc_token_array_size - 1;i++) 59 { 60 rec->fsmarc_token_array[i].next_token_index = i + 1; 61 } 62 rec->fsmarc_token_array[rec->fsmarc_token_array_size-1].next_token_index = MAXstokenID; 63 rec->fsmarc_token_freelist = 0; 64 } 65 66 /*allocates the token and sets it up for a given arc*/ 67 stokenID setup_free_fsmarc_token(srec *rec, FSMarc* arc, arcID fsm_arc_index, miscdata what_to_do_if_fails) 68 { 69 int i; 70 stokenID token_to_return; 71 fsmarc_token *token; 72 73 if (rec->fsmarc_token_freelist == MAXstokenID) 74 { 75 if (what_to_do_if_fails == EXIT_IF_NO_TOKENS) 76 { 77 /*FIX - replace with crec error handling*/ 78 dump_core("setup_free_fsmarc_token: ran out of tokens\n"); 79 } 80 if (what_to_do_if_fails == NULL_IF_NO_TOKENS) 81 { 82 return MAXstokenID; 83 } 84 else 85 { /*no other conditions for now, so just exit*/ 86 /*FIX - replace with crec error handling*/ 87 dump_core("setup_free_fsmarc_token: ran out of tokens\n"); 88 } 89 } 90 91 ASSERT(rec->fsmarc_token_freelist < rec->fsmarc_token_array_size); 92 token_to_return = rec->fsmarc_token_freelist; 93 token = &(rec->fsmarc_token_array[token_to_return]); 94 95 token->FSMarc_index = fsm_arc_index; 96 arc = &(rec->context->FSMarc_list[fsm_arc_index]); 97 token->num_hmm_states = rec->context->hmm_info_for_ilabel[arc->ilabel].num_states; 98 99 for (i = 0;i < token->num_hmm_states;i++) 100 { 101 token->cost[i] = MAXcostdata; 102 token->word[i] = MAXwordID; 103 token->word_backtrace[i] = MAXwtokenID; 104 token->duration[i] = MAXframeID; 105 token->aword_backtrace[i] = AWTNULL; 106 } 107 108 rec->fsmarc_token_freelist = token->next_token_index; 109 110 /* num_fsmarc_tokens_allocated++; */ 111 return token_to_return; 112 } 113 114 115 void free_fsmarc_token(srec *rec, stokenID old_token_index) 116 { 117 fsmarc_token* stoken; 118 ASSERT(old_token_index < rec->fsmarc_token_array_size); 119 stoken = &rec->fsmarc_token_array[old_token_index]; 120 stoken->next_token_index = rec->fsmarc_token_freelist; 121 rec->fsmarc_token_freelist = old_token_index; 122 { int i; 123 for (i = 0; i < stoken->num_hmm_states; i++) 124 if (stoken->aword_backtrace[i] != AWTNULL) 125 free_altword_token_batch(rec, stoken->aword_backtrace[i]); 126 } 127 } 128 129 void sort_fsmarc_token_list(srec* rec, stokenID* ptoken_index) 130 {}; 131 132 /* 133 * word_token management 134 */ 135 136 void initialize_free_word_tokens(srec *rec) 137 { 138 wtokenID i; 139 word_token* wtoken = NULL; 140 141 for (i = 0;i < rec->word_token_array_size;i++) 142 { 143 wtoken = &rec->word_token_array[i]; 144 wtoken->next_token_index = i + 1; 145 } 146 /* last one must point nowhere */ 147 wtoken->next_token_index = MAXwtokenID; 148 rec->word_token_freelist = 0; 149 } 150 151 wtokenID get_free_word_token(srec *rec, miscdata what_to_do_if_fails) 152 { 153 wtokenID token_to_return; 154 word_token* wtoken; 155 156 if (rec->word_token_freelist == MAXwtokenID) 157 { 158 if (what_to_do_if_fails == EXIT_IF_NO_TOKENS) 159 { 160 /*FIX - replace with crec error handling*/ 161 dump_core("get_free_word_token: ran out of tokens\n"); 162 } 163 if (what_to_do_if_fails == NULL_IF_NO_TOKENS) 164 { 165 return MAXwtokenID; 166 } 167 else 168 { /*no other conditions for now, so just exit*/ 169 /*FIX - replace with crec error handling*/ 170 dump_core("get_free_word_token: ran out of tokens\n"); 171 } 172 } 173 174 token_to_return = rec->word_token_freelist; 175 wtoken = &rec->word_token_array[token_to_return]; 176 rec->word_token_freelist = wtoken->next_token_index; 177 178 /*note that we are returning without setting any contents of the token (including next_token_index) 179 leave it for the calling program to take care of that*/ 180 181 return token_to_return; 182 } 183 184 185 186 187 /* 188 * fsmnode_token management 189 */ 190 191 int count_fsmnode_token_list(srec* rec, ftokenID token_index) 192 { 193 int count = 0; 194 195 while (token_index != MAXftokenID) 196 { 197 fsmnode_token* ftoken = &rec->fsmnode_token_array[token_index]; 198 token_index = ftoken->next_token_index; 199 count++; 200 } 201 return count; 202 } 203 204 void initialize_free_fsmnode_tokens(srec *rec) 205 { 206 ftokenID i; 207 fsmnode_token* ftoken = NULL; 208 209 for (i = 0;i < rec->fsmnode_token_array_size;i++) 210 { 211 ftoken = &rec->fsmnode_token_array[i]; 212 ftoken->next_token_index = i + 1; 213 } 214 /* last one must point nowhere */ 215 ftoken->next_token_index = MAXftokenID; 216 rec->fsmnode_token_freelist = 0; 217 } 218 219 ftokenID get_free_fsmnode_token(srec *rec, miscdata what_to_do_if_fails) 220 { 221 ftokenID token_to_return; 222 fsmnode_token* ftoken; 223 224 if (rec->fsmnode_token_freelist == MAXftokenID) 225 { 226 if (what_to_do_if_fails == EXIT_IF_NO_TOKENS) 227 { 228 /*FIX - replace with crec error handling*/ 229 dump_core("get_free_fsmnode_token: ran out of tokens\n"); 230 } 231 if (what_to_do_if_fails == NULL_IF_NO_TOKENS) 232 { 233 return MAXftokenID; 234 } 235 else 236 { /*no other conditions for now, so just exit*/ 237 /*FIX - replace with crec error handling*/ 238 dump_core("get_free_fsmnode_token: ran out of tokens\n"); 239 } 240 } 241 242 token_to_return = rec->fsmnode_token_freelist; 243 ftoken = &rec->fsmnode_token_array[token_to_return]; 244 rec->fsmnode_token_freelist = ftoken->next_token_index; 245 246 /*note that we are returning without setting any contents of the token 247 (including next_token_index) 248 leave it for the calling program to take care of that */ 249 250 return token_to_return; 251 } 252 253 void free_fsmnode_token(srec *rec, ftokenID old_token_index) 254 { 255 fsmnode_token* ftoken; 256 ASSERT(old_token_index < rec->fsmnode_token_array_size); 257 ftoken = &rec->fsmnode_token_array[old_token_index]; 258 ftoken->next_token_index = rec->fsmnode_token_freelist; 259 ftoken->cost = MAXcostdata; 260 rec->fsmnode_token_freelist = old_token_index; 261 if (ftoken->aword_backtrace != AWTNULL) 262 free_altword_token_batch(rec, ftoken->aword_backtrace); 263 } 264 265 /* 266 * altword token management 267 */ 268 269 void initialize_free_altword_tokens(srec *rec) 270 { 271 wtokenID i; 272 altword_token* awtoken = NULL; 273 for (i = 0;i < rec->altword_token_array_size;i++) 274 { 275 awtoken = rec->altword_token_array + i; 276 awtoken->next_token = awtoken + 1; 277 awtoken->costdelta = MAXcostdata; 278 awtoken->refcount = 0; 279 awtoken->costbasis = 0; 280 } 281 /* last one must point nowhere */ 282 awtoken->next_token = NULL; 283 rec->altword_token_freelist = &rec->altword_token_array[0]; 284 rec->altword_token_freelist_len = rec->altword_token_array_size; 285 } 286 287 288 int count_altword_token(srec* rec, altword_token* b) 289 { 290 int num = 0; 291 for (; b; b = b->next_token) { 292 num++; 293 // if(num>9999) ASSERT(0); 294 } 295 return num; 296 } 297 298 299 /* get a free altword token, handle out of memory later!! */ 300 altword_token* get_free_altword_token(srec* rec, miscdata what_to_do_if_fails) 301 { 302 altword_token* awtoken = rec->altword_token_freelist; 303 /* what_to_do_if_fails ... we do not ever expect failure because 304 all get_free's are preceded by repruning, but if there should 305 ever be a failure, we will return NULL and handle it in the 306 caller */ 307 if (!awtoken /*&& what_to_do_if_fails==NULL_IF_NO_TOKENS*/) 308 return awtoken; 309 awtoken->refcount = 1; 310 rec->altword_token_freelist = awtoken->next_token; 311 rec->altword_token_freelist_len--; 312 return awtoken; 313 } 314 315 /* release an altword token */ 316 int free_altword_token(srec* rec, altword_token* old_token) 317 { 318 ASSERT(old_token->refcount >= 1); 319 if (--old_token->refcount <= 0) 320 { 321 old_token->next_token = rec->altword_token_freelist; 322 old_token->costdelta = MAXcostdata; 323 rec->altword_token_freelist = old_token; 324 rec->altword_token_freelist_len++; 325 } 326 return old_token->refcount; /* return zero if truly freed */ 327 } 328 329 altword_token* free_altword_token_batch(srec* rec, altword_token* old_token) 330 { 331 /* char dd[128], *ddp = &dd[0]; */ 332 ASSERT(old_token->refcount >= 1); 333 if (--old_token->refcount <= 0) 334 { 335 altword_token *awtoken, *next_awtoken; 336 for (awtoken = old_token; awtoken != AWTNULL; awtoken = next_awtoken) 337 { 338 next_awtoken = awtoken->next_token; 339 /* *(ddp++) = '0' + awtoken->refcount; */ 340 awtoken->costdelta = MAXcostdata; 341 awtoken->next_token = rec->altword_token_freelist; 342 rec->altword_token_freelist = awtoken; 343 rec->altword_token_freelist_len++; 344 } 345 } 346 return AWTNULL; 347 } 348 349