рдлрдЬреА рдбрд╛рдпрдирд╛рдорд┐рдХ рдЯреЗрдХреНрд╕реНрдЯ рд╕рд░реНрдЪ? рдЗрддрдирд╛ рдбрд░рд╛рд╡рдирд╛ рдирд╣реАрдВ

рд╡реНрд▓рд╛рджрд┐рдореАрд░ рд░реБрдореНрдпрдВрддрд╕реЗрд╡ - рд╕реЗрдВрдЯ рд▓реЙ рдХреЗ рд░реЛрдорд╛рдВрдЪ ... рдмрд┐рд▓реНрд▓реА
рдПрдХ рдордЬрдмреВрдд рд░рд╛рдп рд╣реИ рдХрд┐ рдЧрддрд┐рд╢реАрд▓рддрд╛ рдореЗрдВ рдлрдЬреА рдЦреЛрдЬ (рдСрдирд▓рд╛рдЗрди)
рдЕрдкрдиреА рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдХрд╛рд░рдг рджреБрд░реНрдЧрдоред
рдЕрдЧрд▓рд╛, рд╣рдо рдЗрд╕ рдХрд╖реНрдЯрдкреНрд░рдж рддреНрд░реБрдЯрд┐ рдХреЛ рджреВрд░ рдХрд░реЗрдВрдЧреЗ рдФрд░ рджрд┐рдЦрд╛рдПрдБрдЧреЗ
рдХреНрдпрд╛ рд╕рд╣рдиреАрдп рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ рдЦреЛрдЬ рдЗрдВрдЬрди рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рдЗрддрдирд╛ рдЫреЛрдЯрд╛ рдбреЗрдЯрд╛ рд╣рд░ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИред

рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рд╣реИрдВ:

рдбреЗрдЯрд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред
рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдВрдЧреНрд░реЗрдЬреА рдЕрдиреБрд╡рд╛рдж рдореЗрдВ рдЯреЙрд▓реНрд╕реНрдЯреЙрдп рджреНрд╡рд╛рд░рд╛ рдереЛрдбрд╝рд╛ рд╕рд╛ рдкреБрд╢реНрдХрд┐рди рдФрд░ рджреЛрд╕реНрддреЛрд╡рд╕реНрдХреА, "рдбрд┐рд╡рд╛рдЗрди рдХреЙрдореЗрдбреА" рдФрд░ "рд╡реЙрд░ рдПрдВрдб рдкреАрд╕" рднреА рд▓реЗрдВрдЧреЗред Utf8 рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдореЗрдВ рдХреЗрд╡рд▓ 18 mbред
рдкрд╛рда рдХреА рдкреНрд░рддреНрдпреЗрдХ рдЧреИрд░-рд░рд┐рдХреНрдд рдкрдВрдХреНрддрд┐ рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрди рдЬрд╛рддреА рд╣реИред
рдпрджрд┐ рд░реЗрдЦрд╛ рд▓рдВрдмреА рд╣реИ, рддреЛ рдЗрд╕реЗ 800 рд╢рдмреНрджреЛрдВ рдореЗрдВ рддреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреБрд▓ ~ 160 рд╣рдЬрд╛рд░ рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ

рдбреАрдмреАрдПрдордПрд╕
рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ , рд╣рдо OpenLink Virtuoso рд╕рдВрд╕реНрдХрд░рдг 7.0.0 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЕрдХреЗрд▓реЗ рд╕реА-рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдЖрдкрдХреЛ рд╕рд░реНрд╡рд░ рдХреЛ рдПрдХ рдУрдИрдПрдо рд╢реЗрдпрд░реНрдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА (libvirtuoso-t) рдХреЗ рд░реВрдк рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЙрд╕реА рд╕рдордп рдирд┐рд░реНрдпрд╛рдд рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рд╕рд╛ рдЬрд╛рджреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдбреЗрдЯрд╛ рд╕реНрдХреАрдорд╛
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╢рдмреНрджрдХреЛрд╢:
create table MRC_WORDS ( WD_ID integer, WD_ITSELF nvarchar, WD_COUNT integer, primary key (WD_ID)); 
рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдореЗрдВ рд╢рдмреНрдж, рд╕реНрд╡рдпрдВ рдХреА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдФрд░ рдШрдЯрдирд╛ рдХреА рдЖрд╡реГрддреНрддрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИред рдкрд╛рда рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ рдкрд░ рд╣рд░ рдмрд╛рд░ рдЖрд╡реГрддреНрддрд┐ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕реНрдореГрддрд┐ рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ рдФрд░ рд╕рдордп-рд╕рдордп рдкрд░ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЗрд╕реЗ "рддрд╛рдЬ рджреНрд╡рд╛рд░рд╛" рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЖрд╡реГрддреНрддрд┐ рд░реИрдВрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред

trigrams:
 create table MRC_TRIPLES ( TR_ID integer identity, TR_DATA nvarchar, TR_WORDID integer, primary key(TR_DATA, TR_WORDID, TR_ID)); 
рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдореЗрдВ рдЯреНрд░рд┐рдЧреНрд░рд╛рдо рд╕реНрд╡рдпрдВ рд╣реЛрддрд╛ рд╣реИ, рдЙрд╕ рд╢рдмреНрдж рдХрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рд╡рд╣ рдЖрдпрд╛ рдерд╛, рдФрд░ рд╢рдмреНрдж рдореЗрдВ рдЯреНрд░рд╛рдЗрдЧреНрд░рд╛рдо рдХрдИ рдмрд╛рд░ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (Ex: 'Even cue cue ')

рдШрдЯрдирд╛ рдХреА рд╕реВрдЪреА:
 create table MRC_DATA ( DT_WORDID integer, DT_OID integer, DT_COL integer, DT_POSITION integer, primary key(DT_WORDID, DT_OID, DT_COL, DT_POSITION)); 
рдпрд╣рд╛рдВ рд╣рдо рдпрд╣ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдкрдж рдкрд░ рдХрд┐рд╕ рдкрдж рд╕реЗ рдореБрд▓рд╛рдХрд╛рдд рд╣реБрдИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдбреЗрдЯрд╛:
 create table MRC_TEXT ( TX_ID integer identity, TX_AUTHOR nvarchar, TX_SUBJ nvarchar, TX_STRING nvarchar, TX_LONG_STRING long nvarchar, TX_TS timestamp, primary key (TX_ID)); 
рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ, рддреАрди рдХреЙрд▓рдореЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд▓реЗрдЦрдХ, рдХрд╛рд░реНрдп рдФрд░ рдкрд╛рдаред рдпрджрд┐ рдкрд╛рда 500 рд╡рд░реНрдгреЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рд▓рдВрдмрд╛ рд╣реИ, рддреЛ рдпрд╣ рдмреВрдБрдж рдореЗрдВ рдЧрд┐рд░рддрд╛ рд╣реИред рдЬреАрд╡рди рдореЗрдВ, рдкрд╛рда, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░рд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдмрд╣реБ-рддрд╛рд▓рд┐рдХрд╛ рдмрди рдЬрд╛рдПрдЧрд╛ред рдЗрд╕реЗ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛ рд╣реИ, рдпрд╣ рдпрд╣рд╛рдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ ред

рдЯреНрд░рд┐рдЧрд░ рдбрд╛рд▓реЗрдВ
рд╣рдо рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░рд┐рдЧрд░ рдХреЗ рдЕрдВрджрд░ рд╕рднреА рдЕрдиреБрдХреНрд░рдордг рдХреЛ рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВ:
 create trigger MRC_TEXT_I after insert on MRC_TEXT { declare wordid integer; declare str nvarchar; str := coalesce(TX_STRING, cast(blob_to_string(TX_LONG_STRING)as nvarchar)); MRC_PROCESS_STR_I(str, TX_ID, 1); str := TX_SUBJ; MRC_PROCESS_STR_I(str, TX_ID, 2); str := TX_AUTHOR; MRC_PROCESS_STR_I(str, TX_ID, 3); }; 
рдпрд╛рдиреА рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрдХреНрд░рдорд┐рдд рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП MRC_PROCESS_STR_I рдлрд╝рдВрдХреНрд╢рди рдХреЛ рддреАрди рдмрд╛рд░ рдХрд╣рддреЗ рд╣реИрдВ:
 create procedure MRC_PROCESS_STR_I( in str nvarchar, in oid integer, in col integer) { if (str is not null) { declare vec any; vec := nv_split(str); declare n any; declare wordid any; if (vec <> 0 and vec is not null) { n := length(vec); declare i integer; i := 0; while (i < n) { wordid := treat_nword(vec[i])); if (wordid > 0) { insert into MRC_DATA (DT_WORDID, DT_OID, DT_COL, DT_POSITION) values (wordid, oid, col, i); } i := i + 1; } } } }; 
рдпрд╣рд╛рдВ рд╣рдо nv_split рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╢рдмреНрджреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЛ treat_nword рдХреЗ рд╕рд╛рде рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ MRC_DATA рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВред
рдЙрд▓реНрд▓рд┐рдЦрд┐рдд nv_split рдФрд░ treat_nword C рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ (рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП) рдФрд░ рдкреНрд▓рдЧрдЗрди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реБрд▓рдн рд╣реИрдВред
рдкрд╣рд▓реЗ рдПрдХ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдХреЛ рд╢рдмреНрдж рдХреЛ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдореЗрдВ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЙрдиреНрд╣реЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рд╢рдмреНрдж рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╢рдмреНрдж рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рд╕реНрдореГрддрд┐ рдореЗрдВ рд╢рдмреНрджрдХреЛрд╢ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕реНрдореГрддрд┐ рдореЗрдВ рд╢рдмреНрджрдХреЛрд╢
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд╕реНрдерд╛рдУрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдмрдирддрд╛ рд╣реИ:
рдЕрд▓рдЧ-рдЕрд▓рдЧ, рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЬрдм рдХрд┐рд╕реА рд╢рдмреНрдж рдХреЛ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдореЗрдВ рддреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рд╢рдмреНрдж рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдореЗрдВ рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдЬреБрдбрд╝ рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╢рдмреНрдж рдХреА рд╕рд╣реА рд╢реБрд░реБрдЖрдд рдФрд░ / рдпрд╛ рдЕрдВрдд рдХреЗ рд▓рд┐рдП рдмреЛрдирд╕ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред

рд╢рдмреНрджрд╛рд╡рд▓реА рдЦреЛрдЬ
рд╢рдмреНрджрдХреЛрд╢ рдЦреЛрдЬ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЧрдП рдирдореВрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдФрд░ рдЙрдирдХреА рд╕рдорд╛рдирддрд╛ рд╣реИред
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдЦреЛрдЬ
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдЦреЛрдЬ рдХрд╛ рдХрд╛рд░реНрдп рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рдмреНрджрдХреЛрд╖ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рд░реА рдХрд┐рдП рдЧрдП рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреА рд╕реВрдЪрд┐рдпреЛрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕реНрд░реЛрдд рд╢рдмреНрджреЛрдВ рдХреЗ рдЙрдореНрдореАрджрд╡рд╛рд░ рдкрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдХрдо рдбреЗрдЯрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рд╕рд╛рде, рдЖрдкрдХреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреА рдорд╛рддреНрд░рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдзреНрдпрд╛рди рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд░реБрдЪрд┐ рдХреЗ рд╢рдмреНрджрдХреЛрд╢ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рд▓рд╛рдЗрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВред рддреЛ:
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╕реНрдореГрддрд┐ рдореЗрдВ рд╕рднреА рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдбреЗрдЯрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо:
рд╣рдо рдЕрд▓рдЧ рд╕реЗ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рд╢рдмреНрджрд╛рд╡рд▓реА рдЙрдореНрдореАрджрд╡рд╛рд░ рд╣рд░ рдЬрдЧрд╣ рдмрд╛рд░-рдмрд╛рд░ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╢рд╛рдпрдж рдпрд╣ рдПрдХ рдХрдЪрд░рд╛ рд╢рдмреНрдж рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╢реНрд░реЗрдгреА
рд╣рдо рдПрдХ рдХрд╛рдлреА рдЖрджрд┐рдо рд░реИрдВрдХрд┐рдВрдЧ рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:

рдкреАрдПрд▓ / рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЦреЛрдЬреЗрдВ
рдирд┐рдпрдорд┐рдд рдПрд╕рдХреНрдпреВрдПрд▓ рдореЗрдВ рд╣рдорд╛рд░реА рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдердорд┐рдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
 create procedure MRC_QUERY_STRING_ALL ( in query varchar) { declare vec any; declare len integer; result_names('oid','score'); vec := query_phrase(query); if (vec <> 0 and vec is not null) { len := length(vec); declare i integer; i := 0; while(i<len) { declare oid integer; oid := vec[i]; result (oid, vec[i + 1]); i := i + 2; } } }; create procedure view v_query_phrase_all as MRC_QUERY_STRING_ALL(str)(oid integer, score integer); 

рдХреНрд╡реЗрд░реА рдЕрдм рджрд┐рдЦ рд╕рдХрддреА рд╣реИ:
 select a.TX_ID, a.TX_TS, b.score, a.TX_AUTHOR, a.TX_SUBJ, coalesce (a.TX_STRING, blob_to_string(TX_LONG_STRING)) from MRC_TEXT as a, v_query_phrase_all as b where b.str = 'Posting Date' and a.TX_ID = b.oid; 
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ query_phrase рдлрд╝рдВрдХреНрд╢рди рдПрдХ C рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИ рдФрд░ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХрд░рддрд╛ рд╣реИред

рдмреЗрдВрдЪрдорд╛рд░реНрдХ
i7-3612QM, Win64ред
160 254 рд░рд┐рдХреЙрд░реНрдб рднрд░рдиреЗ рдореЗрдВ 3 рдорд┐рдирдЯ 2 рд╕реЗрдХрдВрдб рдпрд╛ 1.14 рдПрдордПрд╕ рдкреНрд░рддрд┐ рд░рд┐рдХреЙрд░реНрдб рд▓рдЧрддрд╛ рд╣реИред
рдЦреЛрдЬ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдкрд╣рд▓реЗ рджреЛ рд╢рдмреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗ, 1, 2 рдФрд░ 4 рдзрд╛рд░рд╛рдУрдВ рдореЗрдВ рдХреБрд▓ 160,254 рдЦреЛрдЬ рдХреНрд╡реЗрд░реАред рд╣рдо рдХреЗрд╡рд▓ рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЧрдП рд░рд┐рдХреЙрд░реНрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗ, рддрд╛рдХрд┐ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдЙрдард╛рдиреЗ рдФрд░ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордп рдХрд╛ рдзреНрдпрд╛рди рди рд░рдЦрд╛ рдЬрд╛рдПред рд╕реНрдерд╛рдиреАрдп рдУрдбреАрдмреАрд╕реА рдЗрдВрдЯрд░рдлреЗрд╕, рдЯреАрд╕реАрдкреА / рдЖрдИрдкреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдиреАрдп рд▓реЛрдЧреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреНрд╡реЗрд░реА рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдПрди рдзрд╛рдЧреЗрдХреБрд▓ рд╕рдордп1 рдЕрдиреБрд░реЛрдз
111'7 ''4.16 рдорд┐
211'57 ''4.47 рдорд┐
414'515.61 рдорд┐
рдирд┐рд╖реНрдХрд░реНрд╖ рдиреИрддрд┐рдХрддрд╛
рдмрдирд╛рдПрдБ, рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░реЗрдВ, рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ! (C) рдорд╛рдпрд╛рдХреЛрд╡рд╕реНрдХреА

рдкреБрдирд╢реНрдЪ :
рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╕реЗ рдЧреНрд░рдВрде, рдЕрдЪрд╛рдирдХ рдХрд┐рд╕реА рдХреЗ рдХрд╛рдо рдЖрддреЗ рд╣реИрдВ
# рдЕрд▓рдЧ рдХрд░реЗрдВ <stdio.h>
# рдЕрд▓рдЧ рдХрд░рдирд╛ <stdlib.h>
# рдЕрд▓рдЧ рдХрд░реЗрдВ <string.h>

# рдЕрд▓рдЧ рдХрд░рдирд╛ <libutil.h>

#ifdef WIN32
#include <crtdbg.h>
#endif

# рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдПрдВ "sqlnode.h"
# рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдПрдВ "sqlbif.h"
#include "wi.h"
# "Dk.h" рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ

# рдкрд┐рди рдХрд░реЗрдВ <math.h>
# рдЬреАрддрдирд╛ "Caseutils.h"
#include "list_sort.h"
# рдЕрд▓рдЧ рдХрд░реЗрдВ <assert.h>

// # рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ <ksrvext.h>

рд╕реНрдерд┐рд░ id_hash_t * ht_dict_ = NULL;
рд╕реНрдерд┐рд░ dk_hash_t * ht_dict_by_id_ = NULL;
рд╕реНрдерд┐рд░ id_hash_t * ht_triples_ = NULL;
рд╕реНрдерд┐рд░ dk_mutex_t * dict_mtx_ = NULL;

рд╕рдВрд░рдЪрдирд╛ рд╢реНрд░реБрдд_рдЪрд┐рдд__
char * word_;
size_t id_;
size_t count_;
size_t attr_;
};
typedef structure dict_item_s dict_item_t;

рд╕рдВрд░рдЪрдирд╛ triple_item_s {
size_t wordid_;
рд╕рдВрд░рдЪрдирд╛ triple_item_s * next_;
};
typedef structure triple_item_s triple_item_t;

рд╕рдВрд░рдЪрдирд╛ triple_head_s {
lenmem_t lm_;
wchar_t data_ [4];
triple_item_t * list_;
};
typedef рд╕рдВрд░рдЪрдирд╛ triple_head_s triple_head_t;

const wchar_t seps_ [] = L ",ред \ t \ r \ n '\" = *!% ^:; ~ `<> +?"?
const wchar_t glues_ [] = L "() & @ # $: {} / \\ - [] _";

size_t next_wordid (Caddr_t * qst)
{
size_t _id = 0;
query_instance_t * q = (query_instance_t *) qst;
client_connection_t * cli = q-> qi_client;
query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
char buf [1024];
рд╕реНрдкреНрд░рд┐рдВрдЯрдл (buf, "select рдЕрдиреБрдХреНрд░рдо_next ('MRC_WORD_ID')");
рдЕрдЧрд░ (NULL == (stmt = sql_compile (buf, cli, рдЗрд░реЗрдЯ, 0)))
рдЧреЛрдЯреЛ рдЕрдВрдд;

if (NULL! = * * рдЗрд░реЗрдЯ =
qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL
0)))
рдЧреЛрдЯреЛ рдЕрдВрдд;

рдЕрдВрдд:
рдЕрдЧрд░ (lc)
{
lc_next (lc);
_id = (size_t) unbox (lc_nth_col (lc, 0));
}
рдЕрдЧрд░ (lc)
{
lc_free (lc);
lc = NULL;
}
рдЕрдЧрд░ (stmt)
{
qr_free (stmt);
stmt = NULL;
}
рд╡рд╛рдкрд╕реА _id;
}

size_t store_triple (Caddr_t * qst, size_t wordid, const wchar_t * рддреНрд░рд┐рднреБрдЬ)
{
query_instance_t * q = (query_instance_t *) qst;
client_connection_t * cli = q-> qi_client;
query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
char buf [1024];
wchar_t wlt [4];
wcsncpy (wlt, triple, 3);
wlt [3] = 0;

рд╕реНрдкреНрд░рд┐рдВрдЯрдл (buf, "--utf8_execs = yes \ n рдЗрдиреНрд╕рд░реНрдЯ MRC_TRIPLES (TR_DATA, TR_WORDID) рдорд╛рдиреЛрдВ (?)?") рдореЗрдВ рдбрд╛рд▓реЗрдВред
рдЕрдЧрд░ (NULL == (stmt = sql_compile (buf, cli, рдЗрд░реЗрдЯ, 0)))
рдЧреЛрдЯреЛ рдЕрдВрдд;

if (NULL! = * * рдЗрд░реЗрдЯ =
qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL, 2,
": 0", box_wide_string (wlt), QRP_RAW,
": 1", box_num (wordid), QRP_RAW
)))
рдЧреЛрдЯреЛ рдЕрдВрдд;
{
char ** рдЬрдЧрд╣ = NULL;

triple_item_t * pitem = (triple_item_t *) dk_alloc_box_zero (sizeof (triple_item_t), DV_BIN);
triple_head_t * phead = (triple_head_t *) dk_alloc_box_zero (sizeof (triple_head_t), DV_BIN);

phead-> lm_.lm_length = sizeof (phead-> data_);
phead-> lm_.lm_memblock = (char *) phead-> data_;
memcpy (phead-> data_, wlt, sizeof (phead-> data_));

pitem-> wordid_ = wordid;

place = (char **) id_hash_get (ht_triples_, (Caddr_t) рдФрд░ phead-> lm_);
рдЕрдЧрд░ (рдЬрдЧрд╣)
{
triple_head_t * ohead = * (triple_head_t **) рдЬрдЧрд╣;
pitem-> next_ = ohead-> list_;
ohead-> рд╕реВрдЪреА_ = рдкрд┐рдЯреЗрдо;
}
рдЕрдиреНрдпрдерд╛
{
id_hash_set (ht_triples_, (Caddr_t) ((phead-> lm_), (caddr_t) & phead);
рдкреАрдЯрдо-> рдЕрдЧрд▓рд╛_ = рдкрд┐рдЯреЗрдо;
}
}

рдЕрдВрдд:
рдЕрдЧрд░ (lc)
{
lc_free (lc);
lc = NULL;
}
рдЕрдЧрд░ (stmt)
{
qr_free (stmt);
stmt = NULL;
}
рд╡рд╛рдкрд╕реА 0;
}

wchar_t **
nv_split (wchar_t * tmp)
{
wchar_t ** arrest = NULL;
size_t len тАЛтАЛ= wcslen (tmp);
size_t ix = 0;
size_t i;
size_t cnt = 0;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <рд▓реЗрди; рдореИрдВ ++)
{
рдЕрдЧрд░ (NULL! = wcschr (seps_, tmp [i]))
{
tmp [ix ++] = 0;
cnt ++;
}
рдЕрдиреНрдпрдерд╛
{
рдЕрдЧрд░ (NULL == wcschr (glues_, tmp [i]))
tmp [ix ++] = mrc_toupper (tmp [i]);
}
}
tmp [ix] = 0;
cnt = 0;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <рд▓реЗрди; рдореИрдВ ++)
{
рдЕрдЧрд░ (tmp [i])
{
cnt ++;
рдЬрдмрдХрд┐ (i <len && 0! = tmp [++ i]);
}
}
рдпрджрд┐ (cnt)
{
/ * рдФрд░ рдХрдИ рддрддреНрд╡реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдпрд╛ рджреЛ рдмрд╛рд░ рд╡реЗрдХреНрдЯрд░ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░реЗрдВред * /
arr = dk_alloc_box ((cnt * sizeof (Caddr_t)), DV_ARRAY_OF_POINTER);

ix = 0;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <рд▓реЗрди; рдореИрдВ ++)
{
рдЕрдЧрд░ (0! = tmp [i])
{
int loclen = wcslen (tmp + i);
((Caddr_t *) рдЧрд┐рд░рдлреНрддрд╛рд░) [ix] = ((рдЪрд╛рд░ *) dk_alloc_box_zero ((loclen + 1) * sizeof (wchar_t), DV_LONG_WIDE);
memcpy (((Caddr_t *) рдЧрд┐рд░рдлреНрддрд╛рд░) [ix ++], tmp + i, (loclen + 1) * sizeof (wchar_t));
рдЬрдмрдХрд┐ (i <len && 0! = tmp [++ i]);
}
}
}
рд╡рд╛рдкрд╕реА рдЧрд┐рд░рдлреНрддрд╛рд░;
}

caddr_t
bif_nv_split (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
char * me = "nv_split";
Caddr_t arrest = NULL;
Caddr_t arg = bif_arg_unrdf (qst, args, 0, me);
dtp_t dtp = DV_TYPE_OF (arg);
рдЕрдЧрд░ (DV_DB_NULL == dtp || NULL == arg)
{
рд╡рд╛рдкрд╕реА (NULL);
}
рдЕрдЧрд░ (IS_STRING_DTP (dtp))
{
wchar_t * wide = box_utf8_as_wide_char (arg, NULL, strlen (arg), 0, DV_WIDE);
arr = (Caddr_t) nv_split (рд╡рд┐рд╕реНрддреГрдд);
dk_free_box (рдЪреМрдбрд╝реА);
рд╡рд╛рдкрд╕реА рдЧрд┐рд░рдлреНрддрд╛рд░;
}
рдЕрдЧрд░ (IS_WIDE_STRING_DTP (dtp))
{
wchar_t * tmp = wcsdup ((const wchar_t *) arg);
arr = (Caddr_t) nv_split (tmp);
free (tmp);
рд╡рд╛рдкрд╕реА рдЧрд┐рд░рдлреНрддрд╛рд░;
}

{
sqlr_new_error ("22023", "SR007",
"рдлрд╝рдВрдХреНрд╢рди% s рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ nvstring рдпрд╛ NULL рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, a
"рдкреНрд░рдХрд╛рд░% s (% d) рдХрд╛ рдХреЛрдИ рдЖрд░реНрдЧ рдирд╣реАрдВ",
рдореБрдЭреЗ, 1, DV_type_title (dtp), dtp);
}
рд╡рд╛рдкрд╕реА рдЧрд┐рд░рдлреНрддрд╛рд░;
}

caddr_t
bif_treat_nword (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
char * me = "treat_nword";
Caddr_t arg = bif_arg_unrdf (qst, args, 0, me);
рдЗрдВрдЯ рд▓реЗрди;
const wchar_t * wide = (const wchar_t *) arg;
const wchar_t * newwide = NULL;
wchar_t * tmpbuf;
size_t wordid = 0;
dtp_t dtp = DV_TYPE_OF (arg);
рдЕрдЧрд░ (DV_DB_NULL == dtp)
{
рд╡рд╛рдкрд╕реА (NULL);
}
рдЕрдЧрд░ (IS_WIDE_STRING_DTP (dtp))
{
sqlr_new_error ("22023", "SR007",
"рдлрд╝рдВрдХреНрд╢рди% s рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ nvstring рдпрд╛ NULL рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, a
"рдкреНрд░рдХрд╛рд░% s (% d) рдХрд╛ рдХреЛрдИ рдЖрд░реНрдЧ рдирд╣реАрдВ",
рдореБрдЭреЗ, 1, DV_type_title (dtp), dtp);
}
len = wcslen (рдЪреМрдбрд╝рд╛);
tmpbuf = (wchar_t *) _ alloca (sizeof (wchar_t) * * (len + 3));
tmpbuf [0] = L "';
wcscpy (tmpbuf + 1, рдЪреМрдбрд╝реА);
tmpbuf [len + 1] = L "';
tmpbuf [len + 2] = 0;
newwide = tmpbuf;

mutex_enter (dict_mtx_);
{
char * utf8 = box_wide_as_utf8_char ((const char *) рдЪреМрдбрд╝рд╛, len, DV_LONG_STRING);
char ** рдЬрдЧрд╣ = NULL;

place = (char **) id_hash_get (ht_dict_, (Caddr_t) & utf8);
рдЕрдЧрд░ (рдЬрдЧрд╣)
{
dict_item_t * pitem = * (dict_item_t **) рдЬрдЧрд╣;
pitem-> рдЧрд┐рдирддреА _ ++;
dk_free_box (utf8);
wordid = pitem-> id_;
}
рдЕрдиреНрдпрдерд╛
{
query_instance_t * q = (query_instance_t *) qst;
client_connection_t * cli = q-> qi_client;
query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
char buf [1024];

dict_item_t * pitem = dk_alloc_box_zero (sizeof (dict_item_t), DV_BIN);
рдкрд┐рдЯрдо-> рд╢рдмреНрдж_ = utf8;
рдкрд┐рдЯрдо-> рдЧрд┐рдирддреА_ = 1;
wordid = next_wordid (qst);
рдкрд┐рдЯрдо-> рдЖрдИрдбреА_ = рд╡рд░реНрдбрд┐рдб;
id_hash_set (ht_dict_, (Caddr_t) & utf8, (caddr_t) & pitem);
sethash ((void *) wordid, ht_dict_by_id_, (void *) pitem);

sprintf (buf, "--utf8_execs = MRC_WORDS (WD_ITSELF, WD_ID) рдорд╛рди (;?)" рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ?
// рдХрд╛рд╕реНрдЯ (charset_recode ('% s', 'UTF-8', '_WIDE_') nvarchar рдХреЗ рд░реВрдк рдореЗрдВ) ", wordid, utf8);
рдЕрдЧрд░ (NULL! = (stmt = sql_compile (buf, cli, рдЗрд░реЗрдЯ, 0)))
{
* рдЧрд▓рдд =
qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL, 2,
": 0", box_wide_string (newwide), QRP_RAW,
": 1", box_num (wordid), QRP_RAW
);
// * рдЗрд░реЗрдЯ = qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL, 0);
}
рдЕрдЧрд░ (lc)
lc_free (lc);
рдЕрдЧрд░ (stmt)
qr_free (stmt);

{
int len тАЛтАЛ= wcslen (newwide);
int i;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <len-2; i ++)
{
store_triple (qst, wordid, newwide + i);
}
}
}
}
mutex_leave (dict_mtx_);
рд╡рд╛рдкрд╕реА box_num (wordid);
}

int64
рдмреЙрдХреНрд╕ 2 рд▓реЛрдВрдЧ (Caddr_t arg)
{
dtp_t dtp = DV_TYPE_OF (arg);
рдЕрдЧрд░ (dtp == DV_SHORT_INT || dtp == DV_LONG_INT)
рд╡рд╛рдкрд╕реА (int64) (unbox (arg));
рдФрд░ рдЕрдЧрд░ (dtp == DV_SINGLE_FLOAT)
рд╡рд╛рдкрд╕реА (int64) (unbox_float (arg));
рдФрд░ рдЕрдЧрд░ (dtp == DV_DOUBLE_FLOAT)
рд╡рд╛рдкрд╕реА (int64) (unbox_double (arg));
рдФрд░ рдЕрдЧрд░ (dtp == DV_NUMERIC)
{
int64 dt;
num_to_int64 ((num_t) arg, & dt);
рд╡рд╛рдкрд╕реА dt;
}
рдФрд░ рдЕрдЧрд░ (dtp == DV_DB_NULL)
рд╡рд╛рдкрд╕реА (int64) (0);
рдореБрдЦрд░ (рдХреЛ реж);
рд╡рд╛рдкрд╕реА 0;
}

рд╢реВрдиреНрдп рдлреНрд▓рд╢_рдбрд┐рдХреНрдЯ ()
{
char ** key = NULL;
char ** val = NULL;
id_hash_iterator_t рд╣рд┐рдЯ;
id_hash_iterator (& hit, ht_dict_);
рдЬрдмрдХрд┐ (рд╣рд┐рдЯ_рдиреЗрдХреНрд╕реНрдЯ (рдФрд░ рд╣рд┐рдЯ, (Caddr_t *) рдФрд░ рдХреБрдВрдЬреА, (Caddr_t *) * рдФрд░ рд╡реИрд▓))
{
dk_free_box (* key);
dk_free_box (* val);
}
id_hash_clear (ht_dict_);
}

рд╢реВрдиреНрдп flush_triples ()
{
char ** key = NULL;
char ** val = NULL;
id_hash_iterator_t рд╣рд┐рдЯ;
id_hash_iterator (& hit, ht_triples_);
рдЬрдмрдХрд┐ (рд╣рд┐рдЯ_рдиреЗрдХреНрд╕реНрдЯ (рдФрд░ рд╣рд┐рдЯ, (Caddr_t *) рдФрд░ рдХреБрдВрдЬреА, (Caddr_t *) * рдФрд░ рд╡реИрд▓))
{
triple_head_t * phead = * (triple_head_t **) val;
triple_item_t * pit = phead-> list_;

рдЬрдмрдХрд┐ (рдЧрдбреНрдвреЗ)
{
triple_item_t * tmp = pit-> рдЕрдЧрд▓рд╛_;
dk_free_box (рдЧрдбреНрдвреЗ);
рдЧрдбреНрдврд╛ = tmp;
}
dk_free_box (* val);
}
id_hash_clear (ht_triples_);
}

size_t reload_triples (query_instance_t * qst)
{
client_connection_t * cli = qst-> qi_client;
query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
char buf [1024];

flush_triples ();

рд╕реНрдкреНрд░рд┐рдВрдЯрдл (buf, "select TR_DATA, MR__TRIPLES рд╕реЗ TR_WORDID");
рдЕрдЧрд░ (NULL! = (stmt = sql_compile (buf, cli, рдЗрд░реЗрдЯ, 0)))
{
* рдЧрд▓рдд = qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL, 0);
рдЕрдЧрд░ (lc)
{
int64 id = 0;
Caddr_t tmp = 0;
int64 cnt = 0;
char * utf8 = NULL;
char ** рдЬрдЧрд╣ = NULL;
lenmem_t lm;
triple_head_t * phead = NULL;
triple_head_t * ohead = NULL;
triple_item_t * pitem = NULL;

рдЬрдмрдХрд┐ (lc_next (lc))
{
рдЕрдЧрд░ (lc-> lc_error)
{
* рдЧрд▓рдд = box_copy_tree (lc-> lc_error);
рддреЛрдбрд╝;
}
id = box2long (lc_nth_col (lc, 1));
tmp = lc_nth_col (lc, 0);

pitem = (triple_item_t *) dk_alloc_box_zero (sizeof (triple_item_t), DV_BIN);
pitem-> wordid_ = (size_t) id;

lm.lm_length = sizeof (phead-> data_);
lm.lm_memblock = (caddr_t) tmp;

place = (char **) id_hash_get (ht_triples_, (Caddr_t) & lm);
рдЕрдЧрд░ (рдЬрдЧрд╣)
{
ohead = * (triple_head_t **) рдЬрдЧрд╣;
pitem-> next_ = ohead-> list_;
ohead-> рд╕реВрдЪреА_ = рдкрд┐рдЯреЗрдо;
}
рдЕрдиреНрдпрдерд╛
{
phead = (triple_head_t *) dk_alloc_box_zero (sizeof (triple_head_t), DV_BIN);
phead-> list_ = pitem;
phead-> lm_.lm_length = sizeof (phead-> data_);
phead-> lm_.lm_memblock = (Caddr_t) phead-> data_;
memcpy (phead-> data_, tmp, sizeof (phead-> data_));

pitem-> next_ = NULL;
id_hash_set (ht_triples_, (Caddr_t) рдФрд░ phead-> lm_, (Caddr_t) & phead);
}
}
}
}
рдЕрдЧрд░ (lc)
lc_free (lc);
рдЕрдЧрд░ (stmt)
qr_free (stmt);

рд╡рд╛рдкрд╕реА 0;
}

caddr_t
bif_reload_dict (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
query_instance_t * q = (query_instance_t *) qst;
client_connection_t * cli = q-> qi_client;
query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
char buf [1024];

mutex_enter (dict_mtx_);
flush_dict ();

рд╕реНрдкреНрд░рд┐рдВрдЯрдл (buf, "WD_ID, WD_ITSELF, WD_COUNT рдХреЛ MRC_WORDS рд╕реЗ рдЪреБрдиреЗрдВ");
рдЕрдЧрд░ (NULL! = (stmt = sql_compile (buf, cli, рдЗрд░реЗрдЯ, 0)))
{
* рддреНрд░реБрдЯреА = qr_rec_exec (stmt, cli, & lc, (query_instance_t *) qst, NULL, 0);
рдЕрдЧрд░ (lc)
{
int64 id = 0;
Caddr_t tmp = 0;
int64 cnt = 0;
char * utf8 = NULL;
char ** рдЬрдЧрд╣ = NULL;
size_t maxid = 0;

рдЬрдмрдХрд┐ (lc_next (lc))
{
рдЕрдЧрд░ (lc-> lc_error)
{
* рдЧрд▓рдд = box_copy_tree (lc-> lc_error);
рддреЛрдбрд╝;
}
id = box2long (lc_nth_col (lc, 0));
tmp = lc_nth_col (lc, 1);
cnt = box2long (lc_nth_col (lc, 2));
utf8 = box_wide_as_utf8_char (tmp, box_length (tmp) / sizeof (wchar_t) - 1, DV_LONG_STRING);

place = (char **) id_hash_get (ht_dict_, (Caddr_t) & utf8);
рдЕрдЧрд░ (рдЬрдЧрд╣)
{
рдореБрдЦрд░ (рдХреЛ реж);
}
рдЕрдиреНрдпрдерд╛
{
dict_item_t * pitem = dk_alloc_box_zero (sizeof (dict_item_t), DV_BIN);
рдкрд┐рдЯрдо-> рд╢рдмреНрдж_ = utf8;
рдкрд┐рдЯрдо-> рдЧрд┐рдирддреА_ = 1;
pitem-> id_ = (size_t) id;
рдЕрдЧрд░ (рдЕрдзрд┐рдХрддрдо <рдЖрдИрдбреА)
рдореИрдХреНрд╕рд┐рдб = рдЖрдИрдбреА;
id_hash_set (ht_dict_, (Caddr_t) & utf8, (caddr_t) & pitem);
sethash ((void *) id, ht_dict_by_id_, (void *) pitem);
}
}
}
}
рдЕрдЧрд░ (lc)
lc_free (lc);
рдЕрдЧрд░ (stmt)
qr_free (stmt);

reload_triples (q);

mutex_leave (dict_mtx_);
рд╡рд╛рдкрд╕реА 0;
}

// ------------------------------------------------ ---------------------------
// l_dist_raw ()
// рд╕реНрдереИрддрд┐рдХ / рд╕реНрдерд╛рдиреАрдп рдХрд╛рд░реНрдп !!!
//
// рдЙрджреНрджреЗрд╢реНрдп: рджреЛ рддрд╛рд░реЛрдВ (рд╢рдмреНрджреЛрдВ) рдХреЗ рд▓рд┐рдП рдПрд▓ рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
//
// рдЗрдирдкреБрдЯреНрд╕: рдЪрд╛рд░ * str1, * str2 - рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ (рд╢рдмреНрдж) рдХрдореНрдкреЗрдпрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
// int len1, len2 - str1 amd str2 рдХреА рд▓рдВрдмрд╛рдИ рд╕реЗ рдХрдо рд╣реИ
// рдХреНрд░рдорд╢рдГ рдпрд╛ MAX_LDIST_LENред
// рдиреЛрдЯ! рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдЬрд╛рдБрдЪ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИред
// рд╕реНрдЯреИрдХ рдкрд░ рдПрд░рд┐рдпрд░ рдУрд╡рд░рдлреНрд▓реЛ рд╣реЛрдЧрд╛
// рдпрджрд┐ рдпрд╛ рддреЛ рд╕реАрдорд╛ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИред
// рдЖрдЙрдЯрдкреБрдЯ: рдХреЛрдИ рдирд╣реАрдВ
//
// рд░рд┐рдЯрд░реНрди: рдПрд▓ рдбрд┐рд╕реНрдЯреЗрдВрд╕ рд╡реИрд▓реНрдпреВ рд▓реМрдЯрд╛ рджреА рдЬрд╛рддреА рд╣реИ
//
// рдиреЛрдЯ, рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рд╢реАрд░реНрд╖рд▓реЗрдЦ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рджреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИрдВ рдХрд┐
// рдХреЗрд╡рд▓ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
//
// (рд╕рднреА CAPS рдореЗрдВ рдорд╛рди LDIST.H рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ)
//
// ------------------------------------------------ ---------------------------
#define MAX_LDIST_LEN 40 // рдЕрдзрд┐рдХрддрдо рд╢рдмреНрдж рд▓реЗрди рдЯреВ рдХрдореНрдкреЗрдпрд░
#define MIN3 (a, b, c) (a <b??
(a <cред a: c): \
(b <c? b: c))

рдкреВрд░реНрдгрд╛рдВрдХ
l_dist_raw (const wchar_t * str1, const wchar_t * str2, int len1, int len2)
{
int arr1 [MAX_LDIST_LEN + 1];
int arr2 [MAX_LDIST_LEN + 1];
int i, j;
рдЕрдЧрд░ (len1> MAX_LDIST_LEN)
len1 = MAX_LDIST_LEN;
рдЕрдЧрд░ (len2> MAX_LDIST_LEN)
len2 = MAX_LDIST_LEN;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <= len2; i ++)
arr1 [i] = i;

рдХреЗ рд▓рд┐рдП (i = 1; рдореИрдВ <= len1; i ++)
{
arr2 [0] = i;
рдХреЗ рд▓рд┐рдП (j = 1; j <= len2; j ++)
{
int score = (str1 [i-1] == str2 [j-1]); 0: 1;
int i1 = arr2 [j-1] +1;
int i2 = arr1 [j] +1;
int i3 = arr1 [j-1] + рд╕реНрдХреЛрд░;
arr2 [j] = MIN3 (i1, i2, i3); // arr2 [j-1] +1, arr1 [j] +1, arr1 [j] + рд╕реНрдХреЛрд░);
// d [(j-1) * n + i] +1, d [j * n + i-1] +1, d [(j-1) * n + i-1] + рд▓рд╛рдЧрдд);
}
memcpy (arr1, arr2, sizeof (int) * (len2 + 1));
}
рд╡рд╛рдкрд╕реА arr2 [len2];
}

рд╕рдВрд░рдЪрдирд╛ ipair_s {
рдкрд┐рддреГрд▓рдВрдЧ id_;
ptrlong len_;
рдкреЙрдЯреНрд░реЙрдиреНрдЧ рдкреЙрдЬрд╝_;
ptrlong score_;
};
typedef structure ipair_s ipair_t;

рдкреВрд░реНрдгрд╛рдВрдХ
cmp_pairs (const void * a, const void * b)
{
const ipair_t * pa = * (const ipair_t **) a;
const ipair_t * pb = * (const ipair_t **) b;
рдЕрдЧрд░ (pb-> id_ == рдкрд╛-> id_)
рд╡рд╛рдкрд╕реА рдкрд╛-> рд╕реНрдХреЛрд░_ - рдкреАрдмреА-> рд╕реНрдХреЛрд░_;
рд╡рд╛рдкрд╕реА рдкрд╛-> id_ - pb-> id_;
}

int Compar_by_id (const void * a, const void * b, const void * arg)
{
ipair_t * pa = (ipair_t *) a;
ipair_t * pb = (ipair_t *) b;
рд╡рд╛рдкрд╕реА рдкрд╛-> id_ - pb-> id_;
}

int compar_by_score (const void * a, const void * b, const void * arg)
{
ipair_t * pa = (ipair_t *) a;
ipair_t * pb = (ipair_t *) b;
рд╡рд╛рдкрд╕реА pb-> score_ - pa-> score_;
}

dk_set_t
load_oid_list (ipair_t ** words, query_instance_t * q, mem_pool_t * mp)
{
client_connection_t * cli = q-> qi_client;
/ * рд╕реНрдерд┐рд░ * / query_t * stmt = NULL;
local_cursor_t * lc = NULL;
Caddr_t lerr = NULL;
Caddr_t * рдЗрд░реЗрдЯ = & lerr;
dk_set_t out_list = NULL;
char buf [1024];
dk_set_t pair_list = NULL;
ipair_t * рдЖрдЗрдЯрдо = NULL;
size_t i = 0;
size_t len тАЛтАЛ= box_length (рд╢рдмреНрдж) / sizeof (ipair_t *);
size_t cnt = 0;

рдЕрдЧрд░ (NULL == stmt)
{
рд╕реНрдкреНрд░рд┐рдВрдЯрдл (buf, тАЬDT_OID, MR__ATA рд╕реЗ DT_POSITION рдЬрд╣рд╛рдВ DT_WORDID =! ORD) рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ;
if (NULL == (stmt = sql_compile_static (buf, / * рдмреВрдЯрд╕реНрдЯреНрд░реИрдк _ * / cli, рдЗрд░реЗрдЯ, 0)))
рд╡рд╛рдкрд╕реА NULL;
}
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <рд▓реЗрди; рдореИрдВ ++)
{
size_t id;
ipair_t * рдЬреЛрдбрд╝реА = рд╢рдмреНрдж [i];
// рдкреНрд░рд┐рдВрдЯрдл ("\ n ---% d ----- \ n", рдЬреЛрдбрд╝реА-> рдЖрдИрдбреА_);
* рдЗрд░реЗрдЯ = qr_rec_exec (stmt, cli, & lc, (query_instance_t *) q, NULL, 1,
": 0", box_num (рдЬреЛрдбрд╝реА-> id_), QRP_RAW);
рдЕрдЧрд░ (NULL == lc)
рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП;

рдЬрдмрдХрд┐ (lc_next (lc))
{
рдЕрдЧрд░ (lc-> lc_error)
{
* рдЧрд▓рдд = box_copy_tree (lc-> lc_error);
рддреЛрдбрд╝;
}
id = box2long (lc_nth_col (lc, 0));
рдЖрдЗрдЯрдо = (ipair_t *) mp_alloc_box (mp, sizeof (ipair_t), DV_ARRAY_OF_LONG);
рдЖрдЗрдЯрдо-> рдЖрдИрдбреА_ = рдЖрдИрдбреА;
рдЖрдЗрдЯрдо-> рд▓реЗрди_ = рдЬреЛрдбрд╝реА-> рд▓реЗрди_;
рдЖрдЗрдЯрдо-> pos_ = box2long (lc_nth_col (lc, 1));
рдЖрдЗрдЯрдо-> рд╕реНрдХреЛрд░_ = рдЬреЛрдбрд╝реА-> рд╕реНрдХреЛрд░_;
mp_set_push (mp, & рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА, рдЖрдЗрдЯрдо);
cnt ++;
// рдкреНрд░рд┐рдВрдЯрдл ("% рдбреА", рдЖрдИрдбреА);
}
рдЕрдЧрд░ (lc)
lc_free (lc);
}
рдЕрдЧрд░ (stmt)
qr_free (stmt);

// рдЕрдЧрд░ (stmt)
// qr_free (stmt);
// printf ("+% d +", cnt);
рд╡рд╛рдкрд╕реА рд╕реВрдЪреА_рд╕реЙрд░реНрдЯ (рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА, рддреБрд▓рдирд╛_рдмрд╛рд╣реБ, рдирд▓);
}

ipair_t **
get_word_candidates (wchar_t * arg)
{
ipair_t ** res = NULL;
dk_set_t ids_list = NULL;
Caddr_t arrest = NULL;

{
dk_hash_t * ht_ids = NULL;
int maxcount = 1;
size_t i;

wchar_t * word = (wchar_t *) arg;
wchar_t * pbuf = NULL;
size_t isnum = ((* рд╢рдмреНрдж)> = L'0 '&& (* рд╢рдмреНрдж) <= L'9');
size_t len тАЛтАЛ= wcslen (рд╢рдмреНрдж);
// int slen = len;
рдЕрдЧрд░ (len <3 &&! isnum)
{
рд╡рд╛рдкрд╕реА NULL;
}
word = (wchar_t *) box_copy (рд╢рдмреНрдж);
mrc_toupper_str (рд╢рдмреНрдж);

pbuf = (wchar_t *) _ alloca (sizeof (wchar_t) * * (len + 3));
pbuf [0] = L "';
wcscpy (pbuf + 1, рд╢рдмреНрдж);
pbuf [len + 1] = L "';
pbuf [len + 2] = L '\ 0';

ht_ids = hash_table_allocate (101);

mutex_enter (dict_mtx_);
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <(рд▓реЗрди); i ++)
{
char ** рдЬрдЧрд╣ = NULL;
lenmem_t lm;
triple_head_t * phead = NULL;
triple_item_t * pitem = NULL;
wchar_t trbuf [4];
trbuf [0] = mrc_toupper (pbuf [i]);
trbuf [1] = mrc_toupper (pbuf [i + 1]);
trbuf [2] = mrc_toupper (pbuf [i + 2]);
trbuf [3] = L '\ 0';

lm.lm_length = sizeof (phead-> data_);
lm.lm_memblock = (caddr_t) trbuf;

place = (char **) id_hash_get (ht_triples_, (Caddr_t) & lm);
рдЕрдЧрд░ (рдЬрдЧрд╣)
{
phead = * (triple_head_t **) рдЬрдЧрд╣;
рдкреАрдЯрдо = рдлрд╝реЗрдб-> рд╕реВрдЪреА_;
рдЬрдмрдХрд┐ (рдкрд┐рдЯреЗрдо)
{
int wordid = pitem-> wordid_;

int ptr = (int) gethash ((void *) wordid, ht_ids);
рдЕрдЧрд░ (0 == ptr)
sethash ((рд╢реВрдиреНрдп *) рд╡рд░реНрдбрд┐рдб, ht_ids, (рд╢реВрдиреНрдп *) 1);
рдЕрдиреНрдпрдерд╛
{
sethash ((void *) wordid, ht_ids, (void *) (++ ptr));
рдЕрдЧрд░ (ptr> maxcount)
maxcount = ptr;
}

рдкреАрдЯрдо = рдкрд┐рдЯреЗрдо-> рдЕрдЧрд▓рд╛_;
}
}
}
mutex_leave (dict_mtx_);

{
dk_set_t pair_list = NULL;
int nids = 0;
int mx = maxcount;
int nallids = ht_ids-> ht_count;
рд╢реВрдиреНрдп * рдХреБрдВрдЬреА, * рд╡реИрд▓;
dk_hash_iterator_t рд╣рд┐рдЯ;

maxcount = (maxcount + 1) / 2;
рдЕрдЧрд░ (рдЕрдзрд┐рдХрддрдо> = рд▓реЗрди)
maxcount = len - 1;
рдХреЗ рд▓рд┐рдП (dk_hash_iterator (рдФрд░ рд╣рд┐рдЯ, ht_ids);
dk_hit_next (& hit, (void **) & key, (void **) & val);
/ * * /)
{
int wordid = (int) key;
int cnt = (int) val;
рдЕрдЧрд░ (cnt> = maxcount)
{
dict_item_t * pptr = (dict_item_t *) gethash ((рд╢реВрдиреНрдп *) рд╢рдмреНрдж, ht_dict_by_id_);
рдЕрдЧрд░ (рдкреАрдкреАрдЯреАрдЖрд░)
{
ipair_t * рдЖрдЗрдЯрдо = NULL;
wchar_t buf [128];
size_t lbuf, dist, score;
box_utf8_as_wide_char ((Caddr_t) pptr-> word_, (caddr_t) buf, strlen (pptr-> word_), 127, DV_WIDE);
lbuf = wcslen (buf);
dist = l_dist_raw (рд╢рдмреНрдж, buf, рд▓реЗрди, lbuf);
рд╕реНрдХреЛрд░ = 100 - (рдбрд┐рд╕реНрдЯ * * 100) / ((рд▓реЗрди> lbuf); рд▓реЗрди: lbuf);
// рд╕реНрдХреЛрд░ = 100 - (рдбрд┐рд╕реНрдЯ * * 200) / (рд▓реЗрди + lbuf);
рдЕрдЧрд░ (рд╢рдмреНрдж [0]! = buf [0])
рд╕реНрдХреЛрд░ = (рд╕реНрдХреЛрд░ * 3) >> 2;
// рд╕реНрдХреЛрд░ = 100 - (рдбрд┐рд╕реНрдЯ * * 100) / ((рд▓реЗрди> lbuf); рд▓реЗрди: lbuf);
// wprintf (L "% s ->% s (% d) \ n", рд╢рдмреНрдж, buf, рд╕реНрдХреЛрд░);
рдЖрдЗрдЯрдо = (ipair_t *) dk_alloc_box (sizeof (ipair_t), DV_ARRAY_OF_LONG);
рдЖрдЗрдЯрдо-> рдЖрдИрдбреА_ = рд╡рд░реНрдбрд┐рдб;
рдЖрдЗрдЯрдо-> len_ = lbuf;
рдЖрдЗрдЯрдо-> рд╕реНрдХреЛрд░_ = рд╕реНрдХреЛрд░;
dk_set_push (& рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА, рдЖрдЗрдЯрдо);
nids ++;
}
рдореБрдЦрд░ (pptr);
}
}
рдЕрдЧрд░ (рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА)
{
res = (ipair_t **) dk_set_to_array (рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА);
dk_set_free (рдЬреЛрдбрд╝реЗ_рд╕реВрдЪреА);
рдореБрдЦрд░ (nids == box_length (Res) / sizeof (рд╢реВрдиреНрдп *));
qort (рд░реЗрд╕, nids, sizeof (рд╢реВрдиреНрдп *), cmp_pairs);
}
}
hash_table_free (ht_ids);
dk_free_box (рд╢рдмреНрдж);
}
рд╡рд╛рдкрд╕реА Res;
}

caddr_t
bif_get_word_candidates (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
char * me = "get_word_candidates";
ipair_t ** res = NULL;
dk_set_t ids_list = NULL;
Caddr_t arrest = NULL;
Caddr_t arg = bif_arg_unrdf (qst, args, 0, me);
dtp_t dtp = DV_TYPE_OF (arg);
рдЕрдЧрд░ (DV_DB_NULL == dtp)
{
рд╡рд╛рдкрд╕реА (NULL);
}
рдЕрдЧрд░ (IS_WIDE_STRING_DTP (dtp))
{
sqlr_new_error ("22023", "SR007",
"рдлрд╝рдВрдХреНрд╢рди% s рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ nvstring рдпрд╛ NULL рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, a
"рдкреНрд░рдХрд╛рд░% s (% d) рдХрд╛ рдХреЛрдИ рдЖрд░реНрдЧ рдирд╣реАрдВ",
рдореБрдЭреЗ, 1, DV_type_title (dtp), dtp);
}

рдЕрдЧрд░ (0 == ht_dict _-> ht_count)
{
bif_reload_dict (qst, ir_ret, args);
}

res = get_word_candidates ((wchar_t *) arg);

ids_list = load_oid_list (res, (query_instance_t *) qst, NULL);
DO_SET (ipair_t *, рдЖрдЗрдЯрдо, рдФрд░ рдЖрдИрдбреА_рд▓рд┐рд╕реНрдЯ)
{
// рдкреНрд░рд┐рдВрдЯрдл ("% d", рдЖрдЗрдЯрдо-> рдЖрдИрдбреА_);
dk_free_box (рдЖрдЗрдЯрдо);
}
END_DO_SET ();

рд╡рд╛рдкрд╕реА (Caddr_t) res;
}

caddr_t
bif_calc_similarity (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
char * me = "calc_similarity";
Caddr_t arg1 = bif_arg_unrdf (qst, args, 0, me);
Caddr_t arg2 = bif_arg_unrdf (qst, args, 1, me);
dtp_t dtp1 = DV_TYPE_OF (arg1);
dtp_t dtp2 = DV_TYPE_OF (arg2);
рдЕрдЧрд░ (DV_DB_NULL == dtp1 || DV_DB_NULL == dtp2)
{
рд╡рд╛рдкрд╕реА (NULL);
}
if ((! IS_WIDE_STRING_DTP (dtp1)) || (!! IS_WIDE_STRING_DTP (dtp2))
{
sqlr_new_error ("22023", "SR007",
"рдлрд╝рдВрдХреНрд╢рди% s рдХреЛ nvstring рдпрд╛ NULL рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ, a) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ;
}
{
wchar_t * str1 = (wchar_t *) arg1;
wchar_t * str2 = (wchar_t *) arg2;
int l1 = wcslen (str1);
int l2 = wcslen (str2);
int dist = l_dist_raw (str1, str2, l1, l2);
int рд╕реНрдХреЛрд░ = 100 - (рдбрд┐рд╕реНрдЯ * 100) / (((l1> l2); l1: l2);
рдЕрдЧрд░ (str1 [0]! = str2 [0])
рд╕реНрдХреЛрд░ = (рд╕реНрдХреЛрд░ * 3) >> 2;
рд╡рд╛рдкрд╕реА рд╕реНрдХреЛрд░;
}
}
рд╕реНрдерд┐рд░ int g_cnt = 0;
#if рдкрд░рд┐рднрд╛рд╖рд┐рдд WIN32 рдФрд░& рдкрд░рд┐рднрд╛рд╖рд┐рдд (_DEBUG)
static_CrtMemState checkPt1;
#endif

рд▓рдВрдмрд╛ sqrt_long (рд▓рдВрдмрд╛ рдЖрд░)
{
рд▓рдВрдмреЗ рдЯреА, рдмреА, рд╕реА = 0;
рдореБрдЦрд░ (рдЖрд░> = 0);

рдХреЗ рд▓рд┐рдП (рдмреА = 0x10000000; рдмреА! = 0; рдмреА >> = 2)
{
t = c + b;
рд╕реА >> = 1;
рдпрджрд┐ (t <= r)
{
рдЖрд░ = рдЯреА;
рд╕реА + = рдмреА;
}
}
рд╡рд╛рдкрд╕реА ┬й;
}

caddr_t
bif_query_phrase (Caddr_t * qst, Caddr_t * рдЗрд░_рд░реЗрдЯ, State_slot_t ** args)
{
char * me = "query_phrase";
wchar_t ** words = NULL;
ptrlong * res = NULL;
wchar_t * tmp = NULL;
dk_set_t ids_list = NULL;
Caddr_t arrest = NULL;
Caddr_t arg = bif_arg_unrdf (qst, args, 0, me);
dtp_t dtp = DV_TYPE_OF (arg);
int len тАЛтАЛ= 0;
mem_pool_t * mp = mem_pool_alloc ();

#if 0 // рдкрд░рд┐рднрд╛рд╖рд┐рдд WIN32 рдФрд░& рдкрд░рд┐рднрд╛рд╖рд┐рдд (_DEBUG)
_CrtCheckMemory ();
_CrtMemCheckpoint (& checkPt1);
#endif

// рдЕрдЧрд░ (0 == (g_cnt% 1000))
// рдкреНрд░рд┐рдВрдЯрдл ("% d", g_cnt);
++ g_cnt;
рдЕрдЧрд░ (DV_DB_NULL == dtp)
{
рд╡рд╛рдкрд╕реА (NULL);
}
рдЕрдЧрд░ (IS_STRING_DTP (dtp))
{
tmp = box_utf8_as_wide_char (arg, NULL, strlen (arg), 0, DV_WIDE);
words = nv_split (tmp);
dk_free_box (tmp);
}
рдФрд░ рдпрджрд┐ (IS_WIDE_STRING_DTP (dtp))
{
tmp = wcsdup ((const wchar_t *) arg);
words = nv_split (tmp);
free (tmp);
}
рдЕрдиреНрдпрдерд╛
{
sqlr_new_error ("22023", "SR007",
"рдлрд╝рдВрдХреНрд╢рди% s рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ nvstring рдпрд╛ NULL рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, a
"рдкреНрд░рдХрд╛рд░% s (% d) рдХрд╛ рдХреЛрдИ рдЖрд░реНрдЧ рдирд╣реАрдВ",
рдореБрдЭреЗ, 1, DV_type_title (dtp), dtp);
}

рдЕрдЧрд░ (0 == ht_dict _-> ht_count)
{
bif_reload_dict (qst, ir_ret, args);
}

// mutex_enter (рддрд╛рдирд╛рд╢рд╛рд╣реА_mtx_);

рдЕрдЧрд░ (рд╢рдмреНрдж)
{
size_t niters = box_length (рд╢рдмреНрдж) / sizeof (рд╢реВрдиреНрдп *);
dk_set_t рдкрд░рд┐рдгрд╛рдо = NULL;
dk_set_t * iter_holders = mp_alloc_box (mp, niters * sizeof (dk_set_t), DV_ARRAY_OF_POINTER);
dk_set_t * iters = mp_alloc_box (mp, niters * sizeof (dk_set_t), DV_ARRAY_OF_POINTER);
size_t i = 0;
size_t ix = 0;
size_t cnt = 0;
size_t cnt1 = 0;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <niters; i ++)
{
ipair_t ** Res = get_word_candidates ((wchar_t *) рд╢рдмреНрдж [i]);
рдЕрдЧрд░ (Res)
{
iter_kers [ix] = load_oid_list (res, (query_instance_t *) qst, mp);
iters [ix] = iter_holders [ix];
ix ++;
dk_free_tree (res);
}
}
niters = ix;

рдЕрдЧрд░ (niters)
{
int64 min_elem = 0;
int fin = 0;
(рдХреЗ рд▓рд┐рдП! рдлрд┐рди)
{
int bfound = 1;
size_t div = 1;
size_t рд╕реНрдХреЛрд░ = 1;
size_t sumpos = 0;
size_t oldpos = 0;

рдЕрдЧрд░ (iters [0])
рддреЛрдбрд╝;
min_elem = ((ipair_t *) iters [0] -> рдбреЗрдЯрд╛) -> id_;
рдХреЗ рд▓рд┐рдП (i = 0; рдореИрдВ <niters; i ++)
{
рдЕрдЧрд░ (iters [i])
{
ipair_t *ptr = (ipair_t *)iters[i]->data;
div *= 100;
score *= ptr->score_;
if (i)
{
sumpos += abs (oldpos тАФ ptr->pos_);
}
oldpos = ptr->pos_;
if (ptr->id_ != min_elem)
{
bfound = 0;
}
if (ptr->id_ < min_elem)
{
min_elem = ptr->id_;
}
}
}
if (bfound)
{
ipair_t *item = mp_alloc_box(mp, sizeof(ipair_t), DV_BIN);
div /= 100;
score /= div;
if (niters > 1)
sumpos /= (niters тАФ 1);
item->id_ = min_elem;
item->score_ = score/(1 + (sqrt_long(((100*sumpos)/5))/10));
mp_set_push(mp, &results, item);
cnt1++;

//printf (┬лFOUND:%I64d %d\n┬╗, min_elem, score);
}
for (i = 0; i <niters; i++)
{
int bf = bfound;
while (iters[i] && (bf || min_elem == ((ipair_t *)iters[i]->data)->id_))
{
bf = 0;
iters[i] = iters[i]->next;
}
if (!iters[i])
{
fin = 1;
рддреЛрдбрд╝;
}
}
}
}

for (i = 0; i <niters; i++)
{
DO_SET (ipair_t *, item, &iter_holders[i])
{
cnt++;
//dk_free_box(item);
}
END_DO_SET ();
}
//dk_free_box (iters);
//dk_free_box (iter_holders);

//printf ("-%d-", cnt);
len = dk_set_length(results);
//if (len > 100)
{
results = list_sort (results, compare_by_score, NULL);
i = 0;
DO_SET (ipair_t *, entry, &results)
{
entry->len_ = (i >= 100)? 0:1;
рдореИрдВ ++;
}
END_DO_SET();
len = (len>100)?100:len;
}
//results = list_sort (results, compare_by_id, NULL);
i = 0;
res = dk_alloc_box(len * 2 * sizeof(ptrlong), DV_ARRAY_OF_LONG);
DO_SET (ipair_t *, entry, &results)
{
if (entry->len_)
{
res[i++] = (entry->id_);
res[i++] = (entry->score_);
}
//dk_free_box(entry);
cnt1--;
}
END_DO_SET();
//dk_set_free (results);
dk_free_tree (words);
//printf("(%d)", cnt1);
}
//mutex_leave (dict_mtx_);
mp_free (mp);

#if 0//defined WIN32 && defined (_DEBUG)
// _CrtMemDumpAllObjectsSince( NULL );
_CrtMemDumpAllObjectsSince( &checkPt1 );
_CrtMemCheckpoint( &checkPt1 );
_CrtMemDumpStatistics( &checkPt1 );
_CrtCheckMemory( );
#endif
return (caddr_t)res;
}

рд╢реВрдиреНрдп
init_dict (void)
{
dict_mtx_ = mutex_allocate ();
ht_dict_ = id_hash_allocate (2039, sizeof (caddr_t), sizeof (caddr_t), strhash, strhashcmp);
ht_triples_ = id_hash_allocate (2039, sizeof (lenmem_t), sizeof (caddr_t), lenmemhash, lenmemhashcmp);
ht_dict_by_id_ = hash_table_allocate (2039);

bif_define (┬лnv_split┬╗, bif_nv_split);
bif_define (┬лtreat_nword┬╗, bif_treat_nword);
bif_define (┬лcalc_similarity┬╗, bif_calc_similarity);
bif_define (┬лreload_dict┬╗, bif_reload_dict);
bif_define (┬лget_word_candidates┬╗, bif_get_word_candidates);
bif_define (┬лquery_phrase┬╗, bif_query_phrase);
}

void finit_dict()
{
flush_triples();
flush_dict();

hash_table_free (ht_dict_by_id_);
id_hash_free (ht_triples_);
id_hash_free (ht_dict_);
mutex_free (dict_mtx_);
}

extern int f_foreground;

рдкреВрд░реНрдгрд╛рдВрдХ
main (int argc, char *argv[])
{
/*f_foreground = 1;
* FIXME: this could not be done in that way; this is a GPF on WIN32 and
* copy on write on linux; a fuinction from the shared object must be used
* to set it
* /
#ifdef MALLOC_DEBUG
dbg_malloc_enable ();
#endif
build_set_special_server_model ("Mircalo");
VirtuosoServerSetInitHook (init_dict);
рд╡рд╛рдкрд╕реА VirtuosoServerMain (argc, argv);
}

PPS : рд╡реНрд▓рд╛рджрд┐рдореАрд░ рд░реБрдореНрдпрдВрддрд╕реЗрд╡ рдХреА рдЫрд╡рд┐, рдЬрд┐рд╕рдХрд╛ рдЪрд┐рддреНрд░ рдпрд╣рд╛рдВ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рдПрдХ рдЪрд┐рддреНрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред

Source: https://habr.com/ru/post/In206066/


All Articles