/* find the maximum frequency of the same phrase */ static int LoadMaxFreq( const uint16 phoneSeq[], int len ) { int pho_id; Phrase *phrase = ALC( Phrase, 1 ); int maxFreq = FREQ_INIT_VALUE; UserPhraseData *uphrase; pho_id = TreeFindPhrase( 0, len - 1, phoneSeq ); if ( pho_id != -1 ) { GetPhraseFirst( phrase, pho_id ); do { if ( phrase->freq > maxFreq ) maxFreq = phrase->freq; } while( GetPhraseNext( phrase ) ); } free( phrase ); uphrase = UserGetPhraseFirst( phoneSeq ); while ( uphrase ) { if ( uphrase->userfreq > maxFreq ) maxFreq = uphrase->userfreq; uphrase = UserGetPhraseNext( phoneSeq ); } return maxFreq; }
/* find the maximum frequency of the same phrase */ static int LoadMaxFreq( ChewingData *pgdata, const uint16_t phoneSeq[], int len ) { const TreeType *tree_pos; Phrase *phrase = ALC( Phrase, 1 ); int maxFreq = FREQ_INIT_VALUE; UserPhraseData *uphrase; tree_pos = TreeFindPhrase( pgdata, 0, len - 1, phoneSeq ); if ( tree_pos ) { GetPhraseFirst( pgdata, phrase, tree_pos ); do { if ( phrase->freq > maxFreq ) maxFreq = phrase->freq; } while( GetVocabNext( pgdata, phrase ) ); } free( phrase ); uphrase = UserGetPhraseFirst( pgdata, phoneSeq ); while ( uphrase ) { if ( uphrase->userfreq > maxFreq ) maxFreq = uphrase->userfreq; uphrase = UserGetPhraseNext( pgdata, phoneSeq ); } return maxFreq; }
/* find the maximum frequency of the same phrase */ static int LoadMaxFreq(ChewingData *pgdata, const uint16_t phoneSeq[], int len) { const TreeType *tree_pos; Phrase *phrase = ALC(Phrase, 1); int maxFreq = FREQ_INIT_VALUE; int max_userphrase_freq; int ret; tree_pos = TreeFindPhrase(pgdata, 0, len - 1, phoneSeq); if (tree_pos) { GetPhraseFirst(pgdata, phrase, tree_pos); do { if (phrase->freq > maxFreq) maxFreq = phrase->freq; } while (GetVocabNext(pgdata, phrase)); } free(phrase); assert(pgdata->static_data.stmt_userphrase[STMT_USERPHRASE_GET_MAX_FREQ]); ret = UserBindPhone(pgdata, STMT_USERPHRASE_GET_MAX_FREQ, phoneSeq, len); if (ret != SQLITE_OK) { LOG_ERROR("UserBindPhone returns %d", ret); return maxFreq; } ret = sqlite3_step(pgdata->static_data.stmt_userphrase[STMT_USERPHRASE_GET_MAX_FREQ]); if (ret != SQLITE_ROW) return maxFreq; ret = sqlite3_reset(pgdata->static_data.stmt_userphrase[STMT_USERPHRASE_GET_MAX_FREQ]); if (ret != SQLITE_OK) { LOG_ERROR("sqlite3_reset returns %d", ret); return maxFreq; } max_userphrase_freq = sqlite3_column_int(pgdata->static_data.stmt_userphrase[STMT_USERPHRASE_GET_MAX_FREQ], SQL_STMT_USERPHRASE[STMT_USERPHRASE_GET_MAX_FREQ].column [COLUMN_USERPHRASE_USER_FREQ]); if (max_userphrase_freq > maxFreq) maxFreq = max_userphrase_freq; return maxFreq; }
/** @brief Loading all possible phrases after the cursor from long to short into AvailInfo structure.*/ static void SetAvailInfo( AvailInfo *pai, const uint16 phoneSeq[], int nPhoneSeq, int begin, const int bSymbolArrBrkpt[] ) { int end, pho_id; int diff; #ifndef FAFT_CHEWING uint16 userPhoneSeq[ MAX_PHONE_SEQ_LEN ]; #endif pai->nAvail = 0; for ( end = begin; end < nPhoneSeq; end++ ) { diff = end - begin; if ( diff > 0 && bSymbolArrBrkpt[ end ] ) break; pho_id = TreeFindPhrase( begin, end, phoneSeq ); if ( pho_id != -1 ) { /* save it! */ pai->avail[ pai->nAvail ].len = diff + 1; pai->avail[ pai->nAvail ].id = pho_id; pai->nAvail++; } #ifndef FAFT_CHEWING else { memcpy( userPhoneSeq, &phoneSeq[ begin ], sizeof( uint16 ) * ( diff + 1 ) ) ; userPhoneSeq[ diff + 1 ] = 0; if ( UserGetPhraseFirst( userPhoneSeq ) ) { /* save it! */ pai->avail[ pai->nAvail ].len = diff + 1; pai->avail[ pai->nAvail ].id = -1; pai->nAvail++; } else { pai->avail[ pai->nAvail ].len = 0; pai->avail[ pai->nAvail ].id = -1; } } #endif } }
/* load the orginal frequency from the static dict */ static int LoadOriginalFreq(ChewingData *pgdata, const uint16_t phoneSeq[], const char wordSeq[], int len) { const TreeType *tree_pos; int retval; Phrase *phrase = ALC(Phrase, 1); tree_pos = TreeFindPhrase(pgdata, 0, len - 1, phoneSeq); if (tree_pos) { GetPhraseFirst(pgdata, phrase, tree_pos); do { /* find the same phrase */ if (!strcmp(phrase->phrase, wordSeq)) { retval = phrase->freq; free(phrase); return retval; } } while (GetVocabNext(pgdata, phrase)); } free(phrase); return FREQ_INIT_VALUE; }
/* load the orginal frequency from the static dict */ static int LoadOriginalFreq( const uint16 phoneSeq[], const char wordSeq[], int len ) { int pho_id; int retval; Phrase *phrase = ALC( Phrase, 1 ); pho_id = TreeFindPhrase( 0, len - 1, phoneSeq ); if ( pho_id != -1 ) { GetPhraseFirst( phrase, pho_id ); do { /* find the same phrase */ if ( ! strcmp( phrase->phrase, wordSeq ) ) { retval = phrase->freq; free( phrase ); return retval; } } while ( GetPhraseNext( phrase ) ); } free( phrase ); return FREQ_INIT_VALUE; }
static void FindInterval( ChewingData *pgdata, TreeDataType *ptd ) { int end, begin, pho_id; Phrase *p_phrase, *puserphrase, *pdictphrase; UsedPhraseMode i_used_phrase; uint16_t new_phoneSeq[ MAX_PHONE_SEQ_LEN ]; for ( begin = 0; begin < pgdata->nPhoneSeq; begin++ ) { for ( end = begin; end < pgdata->nPhoneSeq; end++ ) { if ( ! CheckBreakpoint( begin, end + 1, pgdata->bArrBrkpt ) ) continue; /* set new_phoneSeq */ memcpy( new_phoneSeq, &pgdata->phoneSeq[ begin ], sizeof( uint16_t ) * ( end - begin + 1 ) ); new_phoneSeq[ end - begin + 1 ] = 0; puserphrase = pdictphrase = NULL; i_used_phrase = USED_PHRASE_NONE; /* check user phrase */ if ( UserGetPhraseFirst( pgdata, new_phoneSeq ) && CheckUserChoose( pgdata, new_phoneSeq, begin, end + 1, &p_phrase, pgdata->selectStr, pgdata->selectInterval, pgdata->nSelect ) ) { puserphrase = p_phrase; } /* check dict phrase */ pho_id = TreeFindPhrase( pgdata, begin, end, pgdata->phoneSeq ); if ( ( pho_id != -1 ) && CheckChoose( pgdata, pho_id, begin, end + 1, &p_phrase, pgdata->selectStr, pgdata->selectInterval, pgdata->nSelect ) ) { pdictphrase = p_phrase; } /* add only one interval, which has the largest freqency * but when the phrase is the same, the user phrase overrides * static dict */ if ( puserphrase != NULL && pdictphrase == NULL ) { i_used_phrase = USED_PHRASE_USER; } else if ( puserphrase == NULL && pdictphrase != NULL ) { i_used_phrase = USED_PHRASE_DICT; } else if ( puserphrase != NULL && pdictphrase != NULL ) { /* the same phrase, userphrase overrides */ if ( ! strcmp( puserphrase->phrase, pdictphrase->phrase ) ) { i_used_phrase = USED_PHRASE_USER; } else { if ( puserphrase->freq > pdictphrase->freq ) { i_used_phrase = USED_PHRASE_USER; } else { i_used_phrase = USED_PHRASE_DICT; } } } switch ( i_used_phrase ) { case USED_PHRASE_USER: AddInterval( ptd, begin, end, -1, puserphrase, IS_USER_PHRASE ); break; case USED_PHRASE_DICT: AddInterval( ptd, begin, end, pho_id, pdictphrase, IS_DICT_PHRASE ); break; case USED_PHRASE_NONE: default: break; } internal_release_Phrase( i_used_phrase, puserphrase, pdictphrase ); } } }
/** @brief Loading all possible phrases after the cursor from long to short into AvailInfo structure.*/ static void SetAvailInfo(ChewingData *pgdata, int begin, int end) { AvailInfo *pai = &(pgdata->availInfo); const uint16_t *phoneSeq = pgdata->phoneSeq; int nPhoneSeq = pgdata->nPhoneSeq; const int *bSymbolArrBrkpt = pgdata->bSymbolArrBrkpt; int symbolArrBrkpt[ARRAY_SIZE(pgdata->bSymbolArrBrkpt)] = { 0 }; const TreeType *tree_pos; int diff; uint16_t userPhoneSeq[MAX_PHONE_SEQ_LEN]; int i, head, head_tmp; int tail, tail_tmp; int pos; head = tail = 0; pai->nAvail = 0; /* * XXX: The phoneSeq, nPhoneSeq skip any symbol in preedit buffer, * while bSymbolArrBrkpt, does not skip any symbol in preedit * buffer. So we need to do some translate here. */ for (i = 0; i < pgdata->chiSymbolBufLen; ++i) { if (bSymbolArrBrkpt[i]) { /* * XXX: If preedit buffer starts with symbol, the pos * will become negative. In this case, we just ignore * this symbol because it does not create any break * point. */ pos = i - CountSymbols(pgdata, i + 1); if (pos >= 0) symbolArrBrkpt[pos] = 1; } } if (pgdata->config.bPhraseChoiceRearward) { for (i = end; i >= begin; i--) { if (symbolArrBrkpt[i]) break; head = i; } head_tmp = end; } else { head_tmp = head = begin; } if (pgdata->config.bPhraseChoiceRearward) { tail_tmp = tail = end; } else { for (i = begin; i < nPhoneSeq; i++) { tail = i; if (symbolArrBrkpt[i]) break; } tail_tmp = begin; } while (head <= head_tmp && tail_tmp <= tail) { diff = tail_tmp - head_tmp; tree_pos = TreeFindPhrase(pgdata, head_tmp, tail_tmp, phoneSeq); if (tree_pos) { /* save it! */ pai->avail[pai->nAvail].len = diff + 1; pai->avail[pai->nAvail].id = tree_pos; pai->nAvail++; } else { memcpy(userPhoneSeq, &phoneSeq[head_tmp], sizeof(uint16_t) * (diff + 1)); userPhoneSeq[diff + 1] = 0; if (UserGetPhraseFirst(pgdata, userPhoneSeq)) { /* save it! */ pai->avail[pai->nAvail].len = diff + 1; pai->avail[pai->nAvail].id = NULL; pai->nAvail++; } else { pai->avail[pai->nAvail].len = 0; pai->avail[pai->nAvail].id = NULL; } UserGetPhraseEnd(pgdata, userPhoneSeq); } if (pgdata->config.bPhraseChoiceRearward) { head_tmp--; } else { tail_tmp++; } } }
/** @brief Loading all possible phrases after the cursor from long to short into AvailInfo structure.*/ static void SetAvailInfo( ChewingData *pgdata, int begin, int end) { AvailInfo *pai = &( pgdata->availInfo ); const uint16_t *phoneSeq = pgdata->phoneSeq; int nPhoneSeq = pgdata->nPhoneSeq; const int *bSymbolArrBrkpt = pgdata->bSymbolArrBrkpt; int pho_id; int diff; uint16_t userPhoneSeq[ MAX_PHONE_SEQ_LEN ]; int i, head, head_tmp; int tail, tail_tmp; head = tail = 0; pai->nAvail = 0; if ( pgdata->config.bPhraseChoiceRearward ) { for ( i = end; i >= begin; i--){ head = i; if ( bSymbolArrBrkpt[ i ] ) break; } head_tmp = end; } else { head_tmp = head = begin; } if ( pgdata->config.bPhraseChoiceRearward ) { tail_tmp = tail = end; } else { for ( i = begin; i < nPhoneSeq; i++ ) { if ( bSymbolArrBrkpt[ i ] ) break; tail = i; } tail_tmp = begin; } while ( head <= head_tmp && tail_tmp <= tail ) { diff = tail_tmp - head_tmp; pho_id = TreeFindPhrase( pgdata, head_tmp, tail_tmp, phoneSeq ); if ( pho_id != -1 ) { /* save it! */ pai->avail[ pai->nAvail ].len = diff + 1; pai->avail[ pai->nAvail ].id = pho_id; pai->nAvail++; } else { memcpy( userPhoneSeq, &phoneSeq[ head_tmp ], sizeof( uint16_t ) * ( diff + 1 ) ) ; userPhoneSeq[ diff + 1 ] = 0; if ( UserGetPhraseFirst( pgdata, userPhoneSeq ) ) { /* save it! */ pai->avail[ pai->nAvail ].len = diff + 1; pai->avail[ pai->nAvail ].id = -1; pai->nAvail++; } else { pai->avail[ pai->nAvail ].len = 0; pai->avail[ pai->nAvail ].id = -1; } } if ( pgdata->config.bPhraseChoiceRearward ) { head_tmp--; } else { tail_tmp++; } } }