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 */
dump_core(char * msg)27 static void dump_core(char *msg)
28 {
29 PLogError ( msg );
30 ASSERT(0);
31 }
32
33 /*
34 * fsmarc_token management
35 */
36
count_fsmarc_token_list(srec * rec,stokenID token_index)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
initialize_free_fsmarc_tokens(srec * rec)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*/
setup_free_fsmarc_token(srec * rec,FSMarc * arc,arcID fsm_arc_index,miscdata what_to_do_if_fails)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
free_fsmarc_token(srec * rec,stokenID old_token_index)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
sort_fsmarc_token_list(srec * rec,stokenID * ptoken_index)129 void sort_fsmarc_token_list(srec* rec, stokenID* ptoken_index)
130 {};
131
132 /*
133 * word_token management
134 */
135
initialize_free_word_tokens(srec * rec)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
get_free_word_token(srec * rec,miscdata what_to_do_if_fails)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
count_fsmnode_token_list(srec * rec,ftokenID token_index)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
initialize_free_fsmnode_tokens(srec * rec)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
get_free_fsmnode_token(srec * rec,miscdata what_to_do_if_fails)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
free_fsmnode_token(srec * rec,ftokenID old_token_index)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
initialize_free_altword_tokens(srec * rec)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
count_altword_token(srec * rec,altword_token * b)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!! */
get_free_altword_token(srec * rec,miscdata what_to_do_if_fails)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 */
free_altword_token(srec * rec,altword_token * old_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
free_altword_token_batch(srec * rec,altword_token * old_token)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