(empty log message)
@@ -16,6 +16,7 @@ | ||
16 | 16 | |
17 | 17 | private DBService m_Service = null; |
18 | 18 | private Corpus m_Corpus = null; |
19 | + private string m_DefaultString; | |
19 | 20 | |
20 | 21 | public bool ParseArguments(string[] args) |
21 | 22 | { |
@@ -80,8 +81,10 @@ | ||
80 | 81 | |
81 | 82 | // DB初期化のためのサービスを得る |
82 | 83 | m_Service = DBService.Create(m_Corpus.DBParam); |
84 | + m_DefaultString = m_Service.GetDefault(); // INSERT文のDEFAULT文字列 | |
83 | 85 | try |
84 | 86 | { |
87 | + m_Service.DropDatabase(); | |
85 | 88 | m_Service.CreateDatabase(); |
86 | 89 | } |
87 | 90 | catch (Exception ex) |
@@ -197,9 +200,9 @@ | ||
197 | 200 | { |
198 | 201 | Lexeme lex = entry.Value; |
199 | 202 | lex.ID = n++; |
200 | - cmd.CommandText = string.Format("INSERT INTO lexemes (id,surface,reading,pronunciation,base_lexeme_ref,part_of_speech_id,ctype_id,cform_id) VALUES ({0},'{1}','{2}','{3}',{4},{5},{6},{7})", | |
203 | + cmd.CommandText = string.Format("INSERT INTO lexemes VALUES ({0},'{1}','{2}','{3}',{4},{5},{6},{7},{8},{9})", | |
201 | 204 | lex.ID, lex.Surface, lex.Reading, lex.Pronunciation, lex.BaseLexeme.ID, |
202 | - lex.PartOfSpeech.ID, lex.CType.ID, lex.CForm.ID); | |
205 | + lex.PartOfSpeech.ID, lex.CType.ID, lex.CForm.ID, m_DefaultString, m_DefaultString); | |
203 | 206 | cmd.ExecuteNonQuery(); |
204 | 207 | Console.Write("> {0}\r", entry.Value.ID+1); |
205 | 208 | } |
@@ -228,6 +231,7 @@ | ||
228 | 231 | |
229 | 232 | int senid = 0; |
230 | 233 | int wordid = 0; |
234 | + int bunsetsuid = 0; | |
231 | 235 | foreach (Sentence sen in m_Corpus.Sentences) |
232 | 236 | { |
233 | 237 | sen.ID = senid++; |
@@ -235,14 +239,37 @@ | ||
235 | 239 | sen.ID, sen.StartChar, sen.EndChar, sen.Text); |
236 | 240 | cmd.ExecuteNonQuery(); |
237 | 241 | |
242 | + foreach (Bunsetsu buns in sen.Bunsetsus) | |
243 | + { | |
244 | + // この文に属する文節すべてのIDを先に確定させておく。 | |
245 | + buns.ID = bunsetsuid++; | |
246 | + } | |
247 | + | |
238 | 248 | foreach (Word word in sen.Words) |
239 | 249 | { |
240 | 250 | word.ID = wordid++; |
241 | - cmd.CommandText = string.Format("INSERT INTO words (id,sentence_id,start_char,end_char,lexeme_id,position) VALUES ({0},{1},{2},{3},{4},{5})", | |
242 | - word.ID, word.Sen.ID, word.StartChar, word.EndChar, word.Lex.ID, word.Pos); | |
251 | + cmd.CommandText = string.Format("INSERT INTO words VALUES ({0},{1},{2},{3},{4},{5},{6},{7})", | |
252 | + word.ID, word.Sen.ID, word.StartChar, word.EndChar, word.Lex.ID, | |
253 | + word.Bunsetsu.ID, m_DefaultString, word.Pos); | |
243 | 254 | cmd.ExecuteNonQuery(); |
244 | 255 | } |
245 | 256 | |
257 | + foreach (Bunsetsu buns in sen.Bunsetsus) | |
258 | + { | |
259 | + try | |
260 | + { | |
261 | + cmd.CommandText = string.Format("INSERT INTO bunsetsus VALUES({0},{1},{2},{3},'{4}')", | |
262 | + buns.ID, buns.Pos, buns.Sen.ID, | |
263 | + (buns.DependsTo == null) ? "null" : buns.DependsTo.ID.ToString(), | |
264 | + buns.DependsAs); | |
265 | + } | |
266 | + catch (Exception ex) | |
267 | + { | |
268 | + Console.WriteLine(ex); | |
269 | + } | |
270 | + cmd.ExecuteNonQuery(); | |
271 | + } | |
272 | + | |
246 | 273 | if (senid > 0 && senid % 500 == 0) |
247 | 274 | { |
248 | 275 | trans.CommitAndContinue(); |
@@ -81,6 +81,15 @@ | ||
81 | 81 | public abstract string GetConnectionString(); |
82 | 82 | |
83 | 83 | /// <summary> |
84 | + /// Insert文のデフォルト文字列を得る | |
85 | + /// </summary> | |
86 | + /// <returns></returns> | |
87 | + public virtual string GetDefault() | |
88 | + { | |
89 | + return "DEFAULT"; | |
90 | + } | |
91 | + | |
92 | + /// <summary> | |
84 | 93 | /// コーパス名に基づきデータベースを作成する |
85 | 94 | /// </summary> |
86 | 95 | public abstract void CreateDatabase(); |
@@ -104,6 +113,7 @@ | ||
104 | 113 | statements.Add(Resources.DropTableLexemesStatement); |
105 | 114 | statements.Add(Resources.DropTableSentencesStatement); |
106 | 115 | statements.Add(Resources.DropTableWordsStatement); |
116 | + statements.Add(Resources.DropTableBunsetsusStatement); | |
107 | 117 | statements.Add(Resources.DropTableSegmentsStatement); |
108 | 118 | statements.Add(Resources.DropTableLinksStatement); |
109 | 119 | statements.Add(Resources.DropTableGroupsStatement); |
@@ -126,6 +136,7 @@ | ||
126 | 136 | statements.Add(Resources.CreateTableLexemesStatement); |
127 | 137 | statements.Add(Resources.CreateTableSentencesStatement); |
128 | 138 | statements.Add(Resources.CreateTableWordsStatement); |
139 | + statements.Add(Resources.CreateTableBunsetsusStatement); | |
129 | 140 | statements.Add(Resources.CreateTableSegmentsStatement); |
130 | 141 | statements.Add(Resources.CreateTableLinksStatement); |
131 | 142 | statements.Add(Resources.CreateTableGroupsStatement); |
@@ -145,13 +156,22 @@ | ||
145 | 156 | statements.Add(Resources.CreateIndexCTypesStatement); |
146 | 157 | statements.Add(Resources.CreateIndexCFormsStatement); |
147 | 158 | statements.Add(Resources.CreateIndexCFormsCTypesStatement); |
148 | - statements.Add(Resources.CreateIndexLexemesStatement); | |
149 | - statements.Add(Resources.CreateIndexSentencesStatement); | |
150 | - statements.Add(Resources.CreateIndexWordsStatement); | |
159 | + statements.Add(Resources.CreateIndexLexemesStatement1); | |
160 | + statements.Add(Resources.CreateIndexLexemesStatement2); | |
161 | + statements.Add(Resources.CreateIndexLexemesStatement3); | |
162 | + statements.Add(Resources.CreateIndexLexemesStatement4); | |
163 | + statements.Add(Resources.CreateIndexLexemesStatement5); | |
164 | + statements.Add(Resources.CreateIndexLexemesStatement6); | |
165 | + statements.Add(Resources.CreateIndexLexemesStatement7); | |
166 | + statements.Add(Resources.CreateIndexSentencesStatement1); | |
167 | + statements.Add(Resources.CreateIndexSentencesStatement2); | |
151 | 168 | // statements.Add(Resources.CreateIndexWordsStatement1); |
152 | 169 | // statements.Add(Resources.CreateIndexWordsStatement2); |
153 | - statements.Add(Resources.CreateIndexSegmentsStatement); | |
154 | - statements.Add(Resources.CreateIndexLinksStatement); | |
170 | + statements.Add(Resources.CreateIndexBunsetsusStatement); | |
171 | + statements.Add(Resources.CreateIndexSegmentsStatement1); | |
172 | + statements.Add(Resources.CreateIndexSegmentsStatement2); | |
173 | + statements.Add(Resources.CreateIndexLinksStatement1); | |
174 | + statements.Add(Resources.CreateIndexLinksStatement2); | |
155 | 175 | statements.Add(Resources.CreateIndexGroupsStatement); |
156 | 176 | statements.Add(Resources.CreateIndexSegmentsGroupsStatement1); |
157 | 177 | statements.Add(Resources.CreateIndexSegmentsGroupsStatement2); |
@@ -185,6 +205,7 @@ | ||
185 | 205 | continue; |
186 | 206 | } |
187 | 207 | cmd.CommandText = statement; |
208 | + cmd.CommandTimeout = 600; // 10 minutes | |
188 | 209 | cmd.ExecuteNonQuery(); |
189 | 210 | } |
190 | 211 | } |
@@ -287,6 +308,8 @@ | ||
287 | 308 | cps.NWords = (int)(long)(query.UniqueResult()); |
288 | 309 | query = session.CreateQuery("select count(*) from Sentence"); |
289 | 310 | cps.NSentences = (int)(long)(query.UniqueResult()); |
311 | + query = session.CreateQuery("select count(*) from Bunsetsu"); | |
312 | + cps.NBunsetsus = (int)(long)(query.UniqueResult()); | |
290 | 313 | query = session.CreateQuery("select count(*) from Segment"); |
291 | 314 | cps.NSegments = (int)(long)(query.UniqueResult()); |
292 | 315 | query = session.CreateQuery("select count(*) from Link"); |
@@ -3,6 +3,7 @@ | ||
3 | 3 | using System.Text; |
4 | 4 | using System.Data.SQLite; |
5 | 5 | using System.Data.Common; |
6 | +using System.IO; | |
6 | 7 | |
7 | 8 | namespace ChaKi.Service.Database |
8 | 9 | { |
@@ -25,7 +26,7 @@ | ||
25 | 26 | |
26 | 27 | public override void DropDatabase() |
27 | 28 | { |
28 | - // dummy | |
29 | + File.Delete(DBParam.Name); | |
29 | 30 | } |
30 | 31 | |
31 | 32 |
@@ -48,5 +49,10 @@ | ||
48 | 49 | { |
49 | 50 | return new SQLiteConnection(GetConnectionString()); |
50 | 51 | } |
52 | + | |
53 | + public override string GetDefault() | |
54 | + { | |
55 | + return "\"\""; | |
56 | + } | |
51 | 57 | } |
52 | 58 | } |
@@ -202,12 +202,11 @@ | ||
202 | 202 | /// <summary> |
203 | 203 | /// 指定した文節を指定した語位置で分離する。 |
204 | 204 | /// </summary> |
205 | - /// <param name="bpos">文節の開始文字位置</param> | |
206 | - /// <param name="epos">文節の終了文字位置</param> | |
207 | - /// <param name="spos">分割文字位置</param> | |
208 | - public void SplitBunsetsu(int bpos, int epos, int spos) | |
205 | + /// <param name="bpos">文節のPos</param> | |
206 | + /// <param name="wpos">語のPos(文節内での位置ではなく、文内の位置)</param> | |
207 | + public void SplitBunsetsu(int bpos, int wpos) | |
209 | 208 | { |
210 | - DepOperation op = new DepOperation(DOType.Split, new object[] { bpos, epos, spos }); | |
209 | + DepOperation op = new DepOperation(DOType.Split, new object[] { bpos, wpos }); | |
211 | 210 | op.Execute(m_Sentence, m_Session); |
212 | 211 | m_History.Record(op); |
213 | 212 | } |
@@ -215,26 +214,25 @@ | ||
215 | 214 | /// <summary> |
216 | 215 | /// 指定した文節を次の文節と併合する。 |
217 | 216 | /// </summary> |
218 | - /// <param name="bpos">文節の開始文字位置</param> | |
219 | - /// <param name="epos">文節の終了文字位置</param> | |
220 | - /// <param name="spos">分割文字位置</param> | |
221 | - public void MergeBunsetsu(int bpos, int epos, int spos) | |
217 | + /// <param name="bpos">文節のPos</param> | |
218 | + /// <param name="wpos">語のPos(文節内での位置ではなく、文内の位置)</param> | |
219 | + public void MergeBunsetsu(int bpos, int wpos) | |
222 | 220 | { |
223 | - DepOperation op = new DepOperation(DOType.Merge, new object[] { bpos, epos, spos }); | |
221 | + DepOperation op = new DepOperation(DOType.Merge, new object[] { bpos, wpos }); | |
224 | 222 | op.Execute(m_Sentence, m_Session); |
225 | 223 | m_History.Record(op); |
226 | 224 | } |
227 | 225 | |
228 | - public void ChangeLinkEnd(Link link, Segment oldseg, Segment newseg) | |
226 | + public void ChangeDependency(int bunsetsuId, int dep_org, int dep_new) | |
229 | 227 | { |
230 | - DepOperation op = new DepOperation(DOType.ChangeLinkEnd, new object[] { link, oldseg, newseg }); | |
228 | + DepOperation op = new DepOperation(DOType.MoveArrow, new object[] { bunsetsuId, dep_org, dep_new }); | |
231 | 229 | op.Execute(m_Sentence, m_Session); |
232 | 230 | m_History.Record(op); |
233 | 231 | } |
234 | 232 | |
235 | - public void ChangeLinkTag(Link link, string oldtag, string newtag) | |
233 | + public void ChangeDependencyTag(int bunsetsuId, string oldtag, string newtag) | |
236 | 234 | { |
237 | - DepOperation op = new DepOperation(DOType.ChangeLinkTag, new object[] { link, oldtag, newtag }); | |
235 | + DepOperation op = new DepOperation(DOType.ChangeTag, new object[] { bunsetsuId, oldtag, newtag }); | |
238 | 236 | op.Execute(m_Sentence, m_Session); |
239 | 237 | m_History.Record(op); |
240 | 238 | } |
@@ -18,16 +18,12 @@ | ||
18 | 18 | // 現在のChar Position |
19 | 19 | int charPos = 0; |
20 | 20 | |
21 | - // 文節データの一時リスト | |
22 | - CabochaBunsetsuList bunsetsuList = new CabochaBunsetsuList(); | |
23 | - | |
24 | - int n = 0; | |
25 | 21 | using (TextReader streamReader = new StreamReader(path, Encoding.GetEncoding(encoding))) |
26 | 22 | { |
23 | + int n = 0; | |
27 | 24 | string s; |
28 | 25 | Sentence sen = new Sentence(); |
29 | - CabochaBunsetsu currentBunsetsu = null; // 最後に読んだ文節 | |
30 | - CabochaBunsetsu terminalBunsetsu = null; // 現在の文内において、係り先が-1であるような文節 | |
26 | + Bunsetsu currentBunsetsu = null; // 最後に読んだ文節 | |
31 | 27 | StringBuilder sb = new StringBuilder(); // Sentenceごとに平文内容を格納 |
32 | 28 | |
33 | 29 | while ((s = streamReader.ReadLine()) != null) |
@@ -37,13 +33,8 @@ | ||
37 | 33 | //文節の開始 |
38 | 34 | try |
39 | 35 | { |
40 | - CabochaBunsetsu buns = this.ParseBunsetsu(sen, charPos, s); | |
36 | + Bunsetsu buns = sen.AddBunsetsu(s); | |
41 | 37 | currentBunsetsu = buns; |
42 | - if (buns.DependsTo == -1) | |
43 | - { | |
44 | - terminalBunsetsu = buns; | |
45 | - } | |
46 | - bunsetsuList.Add(buns); | |
47 | 38 | } |
48 | 39 | catch (Exception) |
49 | 40 | { |
@@ -53,25 +44,12 @@ | ||
53 | 44 | else if (s.StartsWith("EOS")) |
54 | 45 | { |
55 | 46 | // 文の終わり |
56 | - if (currentBunsetsu == null) | |
57 | - { // デフォルト文節を追加(入力がChasen/Mecabの場合のため) | |
58 | - CabochaBunsetsu buns = new CabochaBunsetsu(sen, sen.StartChar, 0, String.Empty, -1); | |
59 | - buns.EndPos = charPos; | |
60 | - bunsetsuList.Add(buns); | |
61 | - currentBunsetsu = buns; | |
62 | - terminalBunsetsu = buns; | |
63 | - } | |
64 | - // 終端ダミー文節を追加 | |
65 | - CabochaBunsetsu dummy = new CabochaBunsetsu(sen, charPos, currentBunsetsu.BunsetsuPos + 1, String.Empty, -1); | |
66 | - bunsetsuList.Add(dummy); | |
67 | - // 係り先が-1である文節をdummyに係るようにする。 | |
68 | - if (terminalBunsetsu != null) | |
47 | + sen.CheckBunsetsus(); // デフォルト文節を追加。係り受け構造全体の整合性を取る。 | |
48 | + | |
49 | + if (++n % 1000 == 0) | |
69 | 50 | { |
70 | - terminalBunsetsu.DependsTo = dummy.BunsetsuPos; | |
71 | - terminalBunsetsu.DependsAs = "D"; | |
51 | + Console.Write("> {0}\r", n); | |
72 | 52 | } |
73 | - | |
74 | - Console.Write("> {0}\r", ++n); | |
75 | 53 | sen.Text = sb.ToString(); |
76 | 54 | sen.EndChar = charPos; |
77 | 55 | m_Corpus.AddSentence(sen); |
@@ -79,7 +57,6 @@ | ||
79 | 57 | sen = new Sentence(); |
80 | 58 | sen.StartChar = charPos; |
81 | 59 | currentBunsetsu = null; |
82 | - terminalBunsetsu = null; | |
83 | 60 | sb = new StringBuilder(); |
84 | 61 | } |
85 | 62 | else if (s.Trim().Length > 0) |
@@ -98,11 +75,8 @@ | ||
98 | 75 | Word w = sen.AddWord(m); |
99 | 76 | w.StartChar = charPos; |
100 | 77 | w.EndChar = charPos + w.CharLength; |
101 | - if (currentBunsetsu != null) // currentBunsetsu はChaSenの場合はnull。 | |
102 | - { | |
103 | - currentBunsetsu.AddWord(w); | |
104 | - } | |
105 | -// w.Bunsetsu = currentBunsetsu; // currentBunsetsu はChaSenの場合はnull。 | |
78 | + w.Bunsetsu = currentBunsetsu; | |
79 | + w.Bunsetsu = currentBunsetsu; // currentBunsetsu はChaSenの場合はnull。 | |
106 | 80 | // 日本語の場合:デリミタなしで平文を再現 |
107 | 81 | sb.Append(m.Surface); |
108 | 82 | //@todo: 英語の場合:平文を再現するにはデリミタで単語を区切る必要がある |
@@ -111,8 +85,10 @@ | ||
111 | 85 | } |
112 | 86 | } |
113 | 87 | } |
88 | + Console.Write("> {0} Sentences Found.\r", n); | |
114 | 89 | } |
115 | 90 | |
91 | +#if false | |
116 | 92 | // BunsetsuをSegment&LinkとしてCorpusに登録 |
117 | 93 | Console.WriteLine("\nChecking Segments (Count={0})", bunsetsuList.Count); |
118 | 94 | n = 0; |
@@ -149,8 +125,10 @@ | ||
149 | 125 | } |
150 | 126 | } |
151 | 127 | Console.WriteLine("> {0}", bunsetsuList.Count); |
128 | +#endif | |
152 | 129 | } |
153 | 130 | |
131 | +#if flase | |
154 | 132 | private CabochaBunsetsu ParseBunsetsu(Sentence sen, int charPos, string s) |
155 | 133 | { |
156 | 134 | char[] bunsetsuSplitPattern = new char[] { ' ' }; |
@@ -178,5 +156,6 @@ | ||
178 | 156 | } |
179 | 157 | return new CabochaBunsetsu(sen, charPos, bunsetsuPos, depType, depBunsetsuId); |
180 | 158 | } |
159 | +#endif | |
181 | 160 | } |
182 | 161 | } |
@@ -248,13 +248,8 @@ | ||
248 | 248 | for (int i = 0; i < depCond.BunsetsuConds.Count; i++) |
249 | 249 | { |
250 | 250 | sb.Append(connector.Get()); |
251 | - sb.AppendFormat("Segment s{0}", i); | |
251 | + sb.AppendFormat("Bunsetsu b{0}", i); | |
252 | 252 | } |
253 | - for (int i = 0; i < depCond.LinkConds.Count; i++) | |
254 | - { | |
255 | - sb.Append(connector.Get()); | |
256 | - sb.AppendFormat("Link k{0}", i); | |
257 | - } | |
258 | 253 | |
259 | 254 | sb.Append(" where "); |
260 | 255 | sb.Append(QueryBuilder.BuildDepSearchQueryWhereClause(iPivot, depCond, lexemeResultSet)); |
@@ -277,9 +272,9 @@ | ||
277 | 272 | // かつ、候補LexemeのどれかにIDが一致していること。 |
278 | 273 | sb.Append(connector.Get()); |
279 | 274 | sb.AppendFormat("w{0}.Lex.ID in {1}", result.No, QueryBuilder.BuildLexemeIDList(result.LexemeList)); |
280 | - // かつ、その語がSegment(i)に属していること | |
275 | + // かつ、その語がBunsetsu(i)に属していること | |
281 | 276 | sb.Append(connector.Get()); |
282 | - sb.AppendFormat("w{0}.StartChar >= s{1}.StartChar and w{0}.StartChar < s{1}.EndChar", result.No, result.BunsetsuNo); | |
277 | + sb.AppendFormat("w{0}.Bunsetsu.ID = b{1}.ID", result.No, result.BunsetsuNo); | |
283 | 278 | // 語の間の順序関係 |
284 | 279 | if (result.Cond.LeftConnection == '-') |
285 | 280 | { |
@@ -298,8 +293,9 @@ | ||
298 | 293 | } |
299 | 294 | else if (result.Cond.RightConnection == '$') |
300 | 295 | { |
301 | - sb.Append(connector.Get()); | |
302 | - sb.AppendFormat("w{0}.EndChar = s{1}.EndChar", result.No, result.BunsetsuNo); | |
296 | + throw new NotImplementedException("'$' is not implemented yet"); | |
297 | +// sb.Append(connector.Get()); | |
298 | +// sb.AppendFormat("w{0}.EndChar = s{1}.EndChar", result.No, result.BunsetsuNo); | |
303 | 299 | } |
304 | 300 | } |
305 | 301 | // Segment間の順序関係 |
@@ -308,27 +304,29 @@ | ||
308 | 304 | if (tcond.LeftConnection == '^') |
309 | 305 | { |
310 | 306 | sb.Append(connector.Get()); |
311 | - sb.AppendFormat("s{0}.StartChar = sen.StartChar", i); | |
307 | + sb.AppendFormat("s{0}.Pos=0", i); | |
312 | 308 | } |
313 | 309 | else if (tcond.LeftConnection == '-') |
314 | 310 | { |
315 | 311 | sb.Append(connector.Get()); |
316 | - sb.AppendFormat("s{0}.EndChar = s{1}.StartChar", i-1, i); | |
312 | + sb.AppendFormat("s{0}.Pos = s{1}.Pos-1", i-1, i); | |
317 | 313 | } |
318 | 314 | else if (tcond.LeftConnection == '<') |
319 | 315 | { |
320 | 316 | sb.Append(connector.Get()); |
321 | - sb.AppendFormat("s{0}.StartChar < s{1}.StartChar", i-1, i); | |
317 | + sb.AppendFormat("s{0}.Pos < s{1}.Pos", i-1, i); | |
322 | 318 | } |
323 | 319 | else if (tcond.RightConnection == '$') |
324 | 320 | { |
325 | - sb.Append(connector.Get()); | |
326 | - sb.AppendFormat("s{0}.EndChar = sen.EndChar", i); | |
321 | + throw new NotImplementedException("'$' is not implemented yet"); | |
322 | +// sb.Append(connector.Get()); | |
323 | +// sb.AppendFormat("s{0}.EndChar = sen.EndChar", i); | |
327 | 324 | } |
328 | 325 | } |
329 | 326 | // Segment間のLink条件 |
330 | 327 | for (int i = 0; i < depCond.LinkConds.Count; i++) |
331 | 328 | { |
329 | + /* | |
332 | 330 | LinkCondition kcond = depCond.LinkConds[i]; |
333 | 331 | sb.Append(connector.Get()); |
334 | 332 | sb.AppendFormat("k{0}.From = s{1} and k{0}.To = s{2}", i, kcond.SegidFrom, kcond.SegidTo); |
@@ -337,6 +335,7 @@ | ||
337 | 335 | sb.Append(connector.Get()); |
338 | 336 | sb.AppendFormat("k{0}.Text = '{1}'", i, kcond.Text); |
339 | 337 | } |
338 | + */ | |
340 | 339 | } |
341 | 340 | return sb.ToString(); |
342 | 341 | } |
@@ -61,9 +61,17 @@ | ||
61 | 61 | } |
62 | 62 | |
63 | 63 | /// <summary> |
64 | - /// CREATE INDEX cforms_ctypes_index ON cforms_ctypes ( | |
65 | - /// cform_id, ctype_id ) に類似しているローカライズされた文字列を検索します。 | |
64 | + /// CREATE INDEX bunsetsu_index ON bunsetsus (sentence_id) に類似しているローカライズされた文字列を検索します。 | |
66 | 65 | /// </summary> |
66 | + internal static string CreateIndexBunsetsusStatement { | |
67 | + get { | |
68 | + return ResourceManager.GetString("CreateIndexBunsetsusStatement", resourceCulture); | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + /// <summary> | |
73 | + /// CREATE INDEX cforms_ctypes_index ON cforms_ctypes (cform_id, ctype_id) に類似しているローカライズされた文字列を検索します。 | |
74 | + /// </summary> | |
67 | 75 | internal static string CreateIndexCFormsCTypesStatement { |
68 | 76 | get { |
69 | 77 | return ResourceManager.GetString("CreateIndexCFormsCTypesStatement", resourceCulture); |
@@ -71,9 +79,7 @@ | ||
71 | 79 | } |
72 | 80 | |
73 | 81 | /// <summary> |
74 | - /// CREATE INDEX cforms_index ON cforms ( | |
75 | - /// id, cform ) | |
76 | - /// に類似しているローカライズされた文字列を検索します。 | |
82 | + /// CREATE INDEX cforms_index ON cforms (cform) に類似しているローカライズされた文字列を検索します。 | |
77 | 83 | /// </summary> |
78 | 84 | internal static string CreateIndexCFormsStatement { |
79 | 85 | get { |
@@ -91,9 +97,7 @@ | ||
91 | 97 | } |
92 | 98 | |
93 | 99 | /// <summary> |
94 | - /// CREATE INDEX ctypes_index ON ctypes ( | |
95 | - /// id, name1, name2, ctype ) | |
96 | - /// に類似しているローカライズされた文字列を検索します。 | |
100 | + /// CREATE INDEX ctypes_index ON ctypes (ctype) に類似しているローカライズされた文字列を検索します。 | |
97 | 101 | /// </summary> |
98 | 102 | internal static string CreateIndexCTypesStatement { |
99 | 103 | get { |
@@ -102,8 +106,7 @@ | ||
102 | 106 | } |
103 | 107 | |
104 | 108 | /// <summary> |
105 | - /// CREATE INDEX groups_index ON groups ( id ) | |
106 | - /// に類似しているローカライズされた文字列を検索します。 | |
109 | + /// に類似しているローカライズされた文字列を検索します。 | |
107 | 110 | /// </summary> |
108 | 111 | internal static string CreateIndexGroupsStatement { |
109 | 112 | get { |
@@ -112,32 +115,89 @@ | ||
112 | 115 | } |
113 | 116 | |
114 | 117 | /// <summary> |
115 | - /// CREATE INDEX lexemes_index ON lexemes ( | |
116 | - /// id, surface, reading, pronunciation, base_lexeme_ref, | |
117 | - /// part_of_speech_id, ctype_id, cform_id ) | |
118 | - /// に類似しているローカライズされた文字列を検索します。 | |
118 | + /// CREATE INDEX lexemes_surface_index ON lexemes (surface) に類似しているローカライズされた文字列を検索します。 | |
119 | 119 | /// </summary> |
120 | - internal static string CreateIndexLexemesStatement { | |
120 | + internal static string CreateIndexLexemesStatement1 { | |
121 | 121 | get { |
122 | - return ResourceManager.GetString("CreateIndexLexemesStatement", resourceCulture); | |
122 | + return ResourceManager.GetString("CreateIndexLexemesStatement1", resourceCulture); | |
123 | 123 | } |
124 | 124 | } |
125 | 125 | |
126 | 126 | /// <summary> |
127 | - /// CREATE INDEX link_index ON links ( | |
128 | - /// id, from_segment_id, to_segment_id ) に類似しているローカライズされた文字列を検索します。 | |
127 | + /// CREATE INDEX lexemes_reading_index ON lexemes (reading) に類似しているローカライズされた文字列を検索します。 | |
129 | 128 | /// </summary> |
130 | - internal static string CreateIndexLinksStatement { | |
129 | + internal static string CreateIndexLexemesStatement2 { | |
131 | 130 | get { |
132 | - return ResourceManager.GetString("CreateIndexLinksStatement", resourceCulture); | |
131 | + return ResourceManager.GetString("CreateIndexLexemesStatement2", resourceCulture); | |
133 | 132 | } |
134 | 133 | } |
135 | 134 | |
136 | 135 | /// <summary> |
137 | - /// CREATE INDEX parts_of_speech_index ON parts_of_speech ( | |
138 | - /// id, name1, name2, name3, name4, part_of_speech ) | |
139 | - /// に類似しているローカライズされた文字列を検索します。 | |
136 | + /// CREATE INDEX lexemes_pronunciation_index ON lexemes (pronunciation) に類似しているローカライズされた文字列を検索します。 | |
140 | 137 | /// </summary> |
138 | + internal static string CreateIndexLexemesStatement3 { | |
139 | + get { | |
140 | + return ResourceManager.GetString("CreateIndexLexemesStatement3", resourceCulture); | |
141 | + } | |
142 | + } | |
143 | + | |
144 | + /// <summary> | |
145 | + /// CREATE INDEX lexemes_base_lexeme_index ON lexemes (base_lexeme_ref) に類似しているローカライズされた文字列を検索します。 | |
146 | + /// </summary> | |
147 | + internal static string CreateIndexLexemesStatement4 { | |
148 | + get { | |
149 | + return ResourceManager.GetString("CreateIndexLexemesStatement4", resourceCulture); | |
150 | + } | |
151 | + } | |
152 | + | |
153 | + /// <summary> | |
154 | + /// CREATE INDEX lexemes_part_of_speech_index ON lexemes (part_of_speech_id) に類似しているローカライズされた文字列を検索します。 | |
155 | + /// </summary> | |
156 | + internal static string CreateIndexLexemesStatement5 { | |
157 | + get { | |
158 | + return ResourceManager.GetString("CreateIndexLexemesStatement5", resourceCulture); | |
159 | + } | |
160 | + } | |
161 | + | |
162 | + /// <summary> | |
163 | + /// CREATE INDEX lexemes_ctype_index ON lexemes (ctype_id) に類似しているローカライズされた文字列を検索します。 | |
164 | + /// </summary> | |
165 | + internal static string CreateIndexLexemesStatement6 { | |
166 | + get { | |
167 | + return ResourceManager.GetString("CreateIndexLexemesStatement6", resourceCulture); | |
168 | + } | |
169 | + } | |
170 | + | |
171 | + /// <summary> | |
172 | + /// CREATE INDEX lexemes_cform_index ON lexemes (cform_id) に類似しているローカライズされた文字列を検索します。 | |
173 | + /// </summary> | |
174 | + internal static string CreateIndexLexemesStatement7 { | |
175 | + get { | |
176 | + return ResourceManager.GetString("CreateIndexLexemesStatement7", resourceCulture); | |
177 | + } | |
178 | + } | |
179 | + | |
180 | + /// <summary> | |
181 | + /// CREATE INDEX link_from_segment_index ON links (from_segment_id) に類似しているローカライズされた文字列を検索します。 | |
182 | + /// </summary> | |
183 | + internal static string CreateIndexLinksStatement1 { | |
184 | + get { | |
185 | + return ResourceManager.GetString("CreateIndexLinksStatement1", resourceCulture); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + /// <summary> | |
190 | + /// CREATE INDEX link_to_segment_index ON links (to_segment_id ) に類似しているローカライズされた文字列を検索します。 | |
191 | + /// </summary> | |
192 | + internal static string CreateIndexLinksStatement2 { | |
193 | + get { | |
194 | + return ResourceManager.GetString("CreateIndexLinksStatement2", resourceCulture); | |
195 | + } | |
196 | + } | |
197 | + | |
198 | + /// <summary> | |
199 | + /// CREATE INDEX parts_of_speech_index ON parts_of_speech (part_of_speech) に類似しているローカライズされた文字列を検索します。 | |
200 | + /// </summary> | |
141 | 201 | internal static string CreateIndexPartsOfSpeechStatement { |
142 | 202 | get { |
143 | 203 | return ResourceManager.GetString("CreateIndexPartsOfSpeechStatement", resourceCulture); |
@@ -163,43 +223,44 @@ | ||
163 | 223 | } |
164 | 224 | |
165 | 225 | /// <summary> |
166 | - /// CREATE INDEX segment_index ON segments ( | |
167 | - /// id, start_char, end_char ) | |
168 | - /// に類似しているローカライズされた文字列を検索します。 | |
226 | + /// CREATE INDEX segment_start_char_index ON segments (start_char) に類似しているローカライズされた文字列を検索します。 | |
169 | 227 | /// </summary> |
170 | - internal static string CreateIndexSegmentsStatement { | |
228 | + internal static string CreateIndexSegmentsStatement1 { | |
171 | 229 | get { |
172 | - return ResourceManager.GetString("CreateIndexSegmentsStatement", resourceCulture); | |
230 | + return ResourceManager.GetString("CreateIndexSegmentsStatement1", resourceCulture); | |
173 | 231 | } |
174 | 232 | } |
175 | 233 | |
176 | 234 | /// <summary> |
177 | - /// CREATE INDEX sentences_index ON sentences ( | |
178 | - /// id ) | |
179 | - /// に類似しているローカライズされた文字列を検索します。 | |
235 | + /// CREATE INDEX segment_end_char_index ON segments (end_char) に類似しているローカライズされた文字列を検索します。 | |
180 | 236 | /// </summary> |
181 | - internal static string CreateIndexSentencesStatement { | |
237 | + internal static string CreateIndexSegmentsStatement2 { | |
182 | 238 | get { |
183 | - return ResourceManager.GetString("CreateIndexSentencesStatement", resourceCulture); | |
239 | + return ResourceManager.GetString("CreateIndexSegmentsStatement2", resourceCulture); | |
184 | 240 | } |
185 | 241 | } |
186 | 242 | |
187 | 243 | /// <summary> |
188 | - /// CREATE INDEX words_index ON words ( | |
189 | - ///id, sentence_id, lexeme_id ) | |
190 | - /// に類似しているローカライズされた文字列を検索します。 | |
244 | + /// CREATE INDEX sentences_start_char_index ON sentences (start_char) に類似しているローカライズされた文字列を検索します。 | |
191 | 245 | /// </summary> |
192 | - internal static string CreateIndexWordsStatement { | |
246 | + internal static string CreateIndexSentencesStatement1 { | |
193 | 247 | get { |
194 | - return ResourceManager.GetString("CreateIndexWordsStatement", resourceCulture); | |
248 | + return ResourceManager.GetString("CreateIndexSentencesStatement1", resourceCulture); | |
195 | 249 | } |
196 | 250 | } |
197 | 251 | |
198 | 252 | /// <summary> |
199 | - /// CREATE INDEX words_sentence_id_index ON words ( | |
200 | - /// sentence_id ASC) | |
201 | - /// に類似しているローカライズされた文字列を検索します。 | |
253 | + /// CREATE INDEX sentences_end_char_index ON sentences (end_char) に類似しているローカライズされた文字列を検索します。 | |
202 | 254 | /// </summary> |
255 | + internal static string CreateIndexSentencesStatement2 { | |
256 | + get { | |
257 | + return ResourceManager.GetString("CreateIndexSentencesStatement2", resourceCulture); | |
258 | + } | |
259 | + } | |
260 | + | |
261 | + /// <summary> | |
262 | + /// CREATE INDEX words_sentence_id_index ON words (sentence_id ASC) に類似しているローカライズされた文字列を検索します。 | |
263 | + /// </summary> | |
203 | 264 | internal static string CreateIndexWordsStatement1 { |
204 | 265 | get { |
205 | 266 | return ResourceManager.GetString("CreateIndexWordsStatement1", resourceCulture); |
@@ -216,6 +277,21 @@ | ||
216 | 277 | } |
217 | 278 | |
218 | 279 | /// <summary> |
280 | + /// CREATE TABLE bunsetsus ( | |
281 | + /// id int primary key, | |
282 | + /// position int, | |
283 | + /// sentence_id int, | |
284 | + /// dep_bunsetsu_id int, | |
285 | + /// dep_relation varchar(16) | |
286 | + ///) に類似しているローカライズされた文字列を検索します。 | |
287 | + /// </summary> | |
288 | + internal static string CreateTableBunsetsusStatement { | |
289 | + get { | |
290 | + return ResourceManager.GetString("CreateTableBunsetsusStatement", resourceCulture); | |
291 | + } | |
292 | + } | |
293 | + | |
294 | + /// <summary> | |
219 | 295 | /// CREATE TABLE cforms_ctypes ( |
220 | 296 | /// cform_id int, |
221 | 297 | /// ctype_id int) に類似しているローカライズされた文字列を検索します。 |
@@ -285,10 +361,11 @@ | ||
285 | 361 | /// reading varchar(255) default '', |
286 | 362 | /// pronunciation varchar(255) default '', |
287 | 363 | /// base_lexeme_ref int not null references lexemes (id), |
288 | - /// updated_at timestamp, | |
289 | 364 | /// part_of_speech_id int not null references parts_of_speech (id), |
290 | 365 | /// ctype_id int not null references ctypes (id), |
291 | - /// cform_id int not null references cform (id) | |
366 | + /// cform_id int not null references cform (id), | |
367 | + /// updated_at timestamp, | |
368 | + /// frequency int default 0 | |
292 | 369 | ///) に類似しているローカライズされた文字列を検索します。 |
293 | 370 | /// </summary> |
294 | 371 | internal static string CreateTableLexemesStatement { |
@@ -378,6 +455,7 @@ | ||
378 | 455 | /// start_char int not null, |
379 | 456 | /// end_char int not null, |
380 | 457 | /// lexeme_id int not null references lexemes (id), |
458 | + /// bunsetsu_id int not null, | |
381 | 459 | /// updated_at timestamp, |
382 | 460 | /// position int |
383 | 461 | ///) に類似しているローカライズされた文字列を検索します。 |
@@ -389,6 +467,15 @@ | ||
389 | 467 | } |
390 | 468 | |
391 | 469 | /// <summary> |
470 | + /// DROP TABLE IF EXISTS bunsetsus に類似しているローカライズされた文字列を検索します。 | |
471 | + /// </summary> | |
472 | + internal static string DropTableBunsetsusStatement { | |
473 | + get { | |
474 | + return ResourceManager.GetString("DropTableBunsetsusStatement", resourceCulture); | |
475 | + } | |
476 | + } | |
477 | + | |
478 | + /// <summary> | |
392 | 479 | /// DROP TABLE IF EXISTS cforms_ctypes に類似しているローカライズされた文字列を検索します。 |
393 | 480 | /// </summary> |
394 | 481 | internal static string DropTableCFormsCTypesStatement { |
@@ -0,0 +1,77 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using ChaKi.VirtualGrid; | |
5 | +using System.Data; | |
6 | + | |
7 | +namespace ChaKi.ToolDialogs | |
8 | +{ | |
9 | + /// <summary> | |
10 | + /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで | |
11 | + /// Just-In-Time データ読み込みを使用して仮想モードを実装する」 | |
12 | + /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx | |
13 | + /// | |
14 | + /// 次に、DataRetriever クラスを定義するコード例を次に示します。 | |
15 | + /// このクラスは、データのページをサーバーから取得する IDataPageRetriever インターフェイスを | |
16 | + /// 実装します。DataRetriever クラスは、Columns プロパティと RowCount プロパティも提供します。 | |
17 | + /// DataGridView コントロールは、これらのプロパティを使用して、必要な列を作成し、 | |
18 | + /// 適切な数の空の行を Rows コレクションに追加します。 | |
19 | + /// 空の行の追加は、テーブル内のデータがすべて存在するようにコントロールが動作するうえで必要です。 | |
20 | + /// これにより、スクロール バーのスクロール ボックスが適切なサイズになり、ユーザーがテーブル内の | |
21 | + /// 任意の行にアクセスできるようになります。行は、スクロール表示されたときにのみ、 | |
22 | + /// CellValueNeeded イベント ハンドラによって値が設定されます。 | |
23 | + /// </summary> | |
24 | + public class LexiconDataRetriever : IDataPageRetriever | |
25 | + { | |
26 | + public LexiconDataRetriever() | |
27 | + { | |
28 | + } | |
29 | + | |
30 | + public int RowCount | |
31 | + { | |
32 | + get | |
33 | + { | |
34 | + return 0; | |
35 | + } | |
36 | + } | |
37 | + | |
38 | + private DataColumnCollection columnsValue = null; | |
39 | + | |
40 | + public DataColumnCollection Columns | |
41 | + { | |
42 | + get | |
43 | + { | |
44 | + // Return the existing value if it has already been determined. | |
45 | + if (columnsValue != null) | |
46 | + { | |
47 | + return columnsValue; | |
48 | + } | |
49 | + DataTable table = new DataTable(); | |
50 | + DataColumn col; | |
51 | + col = new DataColumn("System.StartDate"); | |
52 | + table.Columns.Add(col); | |
53 | + col = new DataColumn("System.ItemPathDisplay"); | |
54 | + table.Columns.Add(col); | |
55 | + col = new DataColumn("System.Size"); | |
56 | + table.Columns.Add(col); | |
57 | + return table.Columns; | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + private string commaSeparatedListOfColumnNamesValue = "System.ItemPathDisplay,System.Size"; | |
62 | + | |
63 | + private string CommaSeparatedListOfColumnNames | |
64 | + { | |
65 | + get | |
66 | + { | |
67 | + return commaSeparatedListOfColumnNamesValue; | |
68 | + } | |
69 | + } | |
70 | + | |
71 | + public DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage) | |
72 | + { | |
73 | + DataTable dt = new DataTable(); | |
74 | + return dt; | |
75 | + } | |
76 | + } | |
77 | +} |
@@ -1,10 +1,8 @@ | ||
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | -using System.ComponentModel; | |
4 | 3 | using System.Data; |
5 | -using System.Drawing; | |
6 | -using System.Text; | |
7 | 4 | using System.Windows.Forms; |
5 | +using ChaKi.VirtualGrid; | |
8 | 6 | using ChaKi.Entity.Corpora; |
9 | 7 | using System.Collections; |
10 | 8 |
@@ -13,11 +11,15 @@ | ||
13 | 11 | public partial class CorpusInfo : Form |
14 | 12 | { |
15 | 13 | private Corpus m_Corpus; |
14 | + private Cache m_MemoryCache; | |
16 | 15 | |
17 | 16 | public CorpusInfo() |
18 | 17 | { |
19 | 18 | InitializeComponent(); |
20 | 19 | m_Corpus = null; |
20 | + | |
21 | + this.dataGridView2.VirtualMode = true; | |
22 | + this.dataGridView2.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView2_CellValueNeeded); | |
21 | 23 | } |
22 | 24 | |
23 | 25 | public void SetCorpus(Corpus c) |
@@ -54,6 +56,18 @@ | ||
54 | 56 | { |
55 | 57 | Lexicon lexicon = m_Corpus.Lex; |
56 | 58 | DataGridView dg = this.dataGridView2; |
59 | + | |
60 | + /* | |
61 | + LexiconDataRetriever retriever = new LexiconDataRetriever(); | |
62 | + m_MemoryCache = new Cache(retriever, 16); | |
63 | + foreach (DataColumn column in retriever.Columns) | |
64 | + { | |
65 | + dataGridView1.Columns.Add(column.ColumnName, column.ColumnName); | |
66 | + } | |
67 | + dg.RowCount = retriever.RowCount; | |
68 | + */ | |
69 | + dg.RowCount = m_Corpus.Lex.Entries.Count; | |
70 | +/* | |
57 | 71 | int r = 0; |
58 | 72 | foreach (KeyValuePair<string, Lexeme> pair in lexicon.Entries) |
59 | 73 | { |
@@ -68,8 +82,35 @@ | ||
68 | 82 | dg[6, r].Value = lex.CForm.Name; |
69 | 83 | r++; |
70 | 84 | } |
85 | + * */ | |
71 | 86 | } |
72 | 87 | |
88 | + private void dataGridView2_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) | |
89 | + { | |
90 | + Lexeme lex = null; | |
91 | + try | |
92 | + { | |
93 | + lex = m_Corpus.Lex.Entries.Values[e.RowIndex]; | |
94 | + } | |
95 | + catch (Exception) | |
96 | + { | |
97 | + return; | |
98 | + } | |
99 | + | |
100 | + switch (e.ColumnIndex) | |
101 | + { | |
102 | + case 0: e.Value = lex.Surface; break; | |
103 | + case 1: e.Value = lex.Reading; break; | |
104 | + case 2: e.Value = lex.Pronunciation; break; | |
105 | + case 3: e.Value = (lex.BaseLexeme != null) ? lex.BaseLexeme.Surface : ""; break; | |
106 | + case 4: e.Value = lex.PartOfSpeech.Name; break; | |
107 | + case 5: e.Value = lex.CType.Name; break; | |
108 | + case 6: e.Value = lex.CForm.Name; break; | |
109 | + case 7: e.Value = lex.Frequency; break; | |
110 | + } | |
111 | +// e.Value = this.m_MemoryCache.RetrieveElement(e.RowIndex, e.ColumnIndex); | |
112 | + } | |
113 | + | |
73 | 114 | private void LoadPOS() |
74 | 115 | { |
75 | 116 | this.propertyTree1.Cps = m_Corpus; |
@@ -0,0 +1,175 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using System.Data; | |
5 | + | |
6 | +namespace ChaKi.VirtualGrid | |
7 | +{ | |
8 | + /// <summary> | |
9 | + /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで | |
10 | + /// Just-In-Time データ読み込みを使用して仮想モードを実装する」 | |
11 | + /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx | |
12 | + /// | |
13 | + /// 次に、Cache クラスを定義するコード例を示します。このクラスは、 | |
14 | + /// IDataPageRetriever 実装によって設定される 2 ページのデータを管理します。 | |
15 | + /// Cache クラスは、内側の DataPage 構造体を定義します。 | |
16 | + /// この構造体は、値を 1 つのキャッシュ ページに保存する DataTable を含み、 | |
17 | + /// ページの上下の境界を表す行インデックスを計算します。 | |
18 | + /// | |
19 | + /// Cache クラスは、構築時に 2 ページのデータを読み込みます。 | |
20 | + /// CellValueNeeded イベントが値を要求すると、Cache オブジェクトは、 | |
21 | + /// その 2 ページのいずれかに値が存在するかどうか確認し、値が存在する場合には返します。 | |
22 | + /// 値がローカルに存在しない場合、Cache は、2 つのページのうちで、 | |
23 | + /// 現在表示されている行から遠い方のページを特定し、そのページを、 | |
24 | + /// 要求されている値を含む新しいページと置き換えて、値を返します。 | |
25 | + /// | |
26 | + /// データ ページの行数と、画面に同時に表示できる行数が一致することを前提に、 | |
27 | + /// このモデルでは、テーブルをページングしているユーザーが、 | |
28 | + /// 直前に表示されたページに効率的に復帰できます。 | |
29 | + /// </summary> | |
30 | + public class Cache | |
31 | + { | |
32 | + private static int RowsPerPage; | |
33 | + | |
34 | + // Represents one page of data. | |
35 | + public struct DataPage | |
36 | + { | |
37 | + public DataTable table; | |
38 | + private int lowestIndexValue; | |
39 | + private int highestIndexValue; | |
40 | + | |
41 | + public DataPage(DataTable table, int rowIndex) | |
42 | + { | |
43 | + this.table = table; | |
44 | + lowestIndexValue = MapToLowerBoundary(rowIndex); | |
45 | + highestIndexValue = MapToUpperBoundary(rowIndex); | |
46 | + System.Diagnostics.Debug.Assert(lowestIndexValue >= 0); | |
47 | + System.Diagnostics.Debug.Assert(highestIndexValue >= 0); | |
48 | + } | |
49 | + | |
50 | + public int LowestIndex | |
51 | + { | |
52 | + get | |
53 | + { | |
54 | + return lowestIndexValue; | |
55 | + } | |
56 | + } | |
57 | + | |
58 | + public int HighestIndex | |
59 | + { | |
60 | + get | |
61 | + { | |
62 | + return highestIndexValue; | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + public static int MapToLowerBoundary(int rowIndex) | |
67 | + { | |
68 | + // Return the lowest index of a page containing the given index. | |
69 | + return (rowIndex / RowsPerPage) * RowsPerPage; | |
70 | + } | |
71 | + | |
72 | + private static int MapToUpperBoundary(int rowIndex) | |
73 | + { | |
74 | + // Return the highest index of a page containing the given index. | |
75 | + return MapToLowerBoundary(rowIndex) + RowsPerPage - 1; | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + private DataPage[] cachePages; | |
80 | + private IDataPageRetriever dataSupply; | |
81 | + | |
82 | + public Cache(IDataPageRetriever dataSupplier, int rowsPerPage) | |
83 | + { | |
84 | + dataSupply = dataSupplier; | |
85 | + Cache.RowsPerPage = rowsPerPage; | |
86 | + LoadFirstTwoPages(); | |
87 | + } | |
88 | + | |
89 | + // Sets the value of the element parameter if the value is in the cache. | |
90 | + private bool IfPageCached_ThenSetElement(int rowIndex, int columnIndex, ref string element) | |
91 | + { | |
92 | + if (IsRowCachedInPage(0, rowIndex)) | |
93 | + { | |
94 | + element = cachePages[0].table.Rows[rowIndex % RowsPerPage][columnIndex].ToString(); | |
95 | + return true; | |
96 | + } | |
97 | + else if (IsRowCachedInPage(1, rowIndex)) | |
98 | + { | |
99 | + element = cachePages[1].table.Rows[rowIndex % RowsPerPage][columnIndex].ToString(); | |
100 | + return true; | |
101 | + } | |
102 | + | |
103 | + return false; | |
104 | + } | |
105 | + | |
106 | + public string RetrieveElement(int rowIndex, int columnIndex) | |
107 | + { | |
108 | + string element = null; | |
109 | + | |
110 | + if (IfPageCached_ThenSetElement(rowIndex, columnIndex, ref element)) | |
111 | + { | |
112 | + return element; | |
113 | + } | |
114 | + else | |
115 | + { | |
116 | + return RetrieveData_CacheIt_ThenReturnElement(rowIndex, columnIndex); | |
117 | + } | |
118 | + } | |
119 | + | |
120 | + private void LoadFirstTwoPages() | |
121 | + { | |
122 | + cachePages = new DataPage[]{ | |
123 | + new DataPage(dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(0), RowsPerPage), 0), | |
124 | + new DataPage(dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(RowsPerPage), RowsPerPage), RowsPerPage)}; | |
125 | + } | |
126 | + | |
127 | + private string RetrieveData_CacheIt_ThenReturnElement(int rowIndex, int columnIndex) | |
128 | + { | |
129 | + // Retrieve a page worth of data containing the requested value. | |
130 | + DataTable table = dataSupply.SupplyPageOfData(DataPage.MapToLowerBoundary(rowIndex), RowsPerPage); | |
131 | + | |
132 | + // Replace the cached page furthest from the requested cell | |
133 | + // with a new page containing the newly retrieved data. | |
134 | + cachePages[GetIndexToUnusedPage(rowIndex)] = new DataPage(table, rowIndex); | |
135 | + | |
136 | + return RetrieveElement(rowIndex, columnIndex); | |
137 | + } | |
138 | + | |
139 | + // Returns the index of the cached page most distant from the given index | |
140 | + // and therefore least likely to be reused. | |
141 | + private int GetIndexToUnusedPage(int rowIndex) | |
142 | + { | |
143 | + if (rowIndex > cachePages[0].HighestIndex && | |
144 | + rowIndex > cachePages[1].HighestIndex) | |
145 | + { | |
146 | + int offsetFromPage0 = rowIndex - cachePages[0].HighestIndex; | |
147 | + int offsetFromPage1 = rowIndex - cachePages[1].HighestIndex; | |
148 | + if (offsetFromPage0 < offsetFromPage1) | |
149 | + { | |
150 | + return 1; | |
151 | + } | |
152 | + return 0; | |
153 | + } | |
154 | + else | |
155 | + { | |
156 | + int offsetFromPage0 = cachePages[0].LowestIndex - rowIndex; | |
157 | + int offsetFromPage1 = cachePages[1].LowestIndex - rowIndex; | |
158 | + if (offsetFromPage0 < offsetFromPage1) | |
159 | + { | |
160 | + return 1; | |
161 | + } | |
162 | + return 0; | |
163 | + } | |
164 | + | |
165 | + } | |
166 | + | |
167 | + // Returns a value indicating whether the given row index is contained | |
168 | + // in the given DataPage. | |
169 | + private bool IsRowCachedInPage(int pageNumber, int rowIndex) | |
170 | + { | |
171 | + return rowIndex <= cachePages[pageNumber].HighestIndex && | |
172 | + rowIndex >= cachePages[pageNumber].LowestIndex; | |
173 | + } | |
174 | + } | |
175 | +} |
@@ -0,0 +1,26 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Text; | |
4 | +using System.Data; | |
5 | + | |
6 | +namespace ChaKi.VirtualGrid | |
7 | +{ | |
8 | + /// <summary> | |
9 | + /// 参考ページ:「方法 Windows フォーム DataGridView コントロールで | |
10 | + /// Just-In-Time データ読み込みを使用して仮想モードを実装する」 | |
11 | + /// http://msdn2.microsoft.com/ja-jp/library/ms171625(VS.80).aspx | |
12 | + /// | |
13 | + /// DataRetriever クラスによって実装される IDataPageRetriever インターフェイスを定義する | |
14 | + /// コード例を次に示します。このインターフェイスで宣言されているメソッドは、 | |
15 | + /// 初期行インデックスと 1 ページのデータの行数を要求する SupplyPageOfData メソッドだけです。 | |
16 | + /// これらの値は、データ ソースからデータのサブセットを取得する実装側で使用されます。 | |
17 | + /// | |
18 | + /// Cache オブジェクトは、このインターフェイスの実装を構築時に使用して、 | |
19 | + /// データの最初の 2 ページを読み込みます。未キャッシュのデータが必要になると、 | |
20 | + /// キャッシュはこれらのページのいずれかを破棄し、IDataPageRetriever にその値を含む新しいページを要求します。 | |
21 | + /// </summary> | |
22 | + public interface IDataPageRetriever | |
23 | + { | |
24 | + DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage); | |
25 | + } | |
26 | +} |
@@ -24,6 +24,7 @@ | ||
24 | 24 | public int NLexemes { get; set; } |
25 | 25 | public int NWords { get; set; } |
26 | 26 | public int NSentences { get; set; } |
27 | + public int NBunsetsus { get; set; } | |
27 | 28 | public int NSegments { get; set; } |
28 | 29 | public int NLinks { get; set; } |
29 | 30 | public int NGroups { get; set; } |
@@ -129,6 +130,7 @@ | ||
129 | 130 | cprops.Add(new CorpusProperty("#Words", this.NWords.ToString())); |
130 | 131 | cprops.Add(new CorpusProperty("#Lexemes", this.NLexemes.ToString())); |
131 | 132 | cprops.Add(new CorpusProperty("#Sentences", this.NSentences.ToString())); |
133 | + cprops.Add(new CorpusProperty("#Bunsetsu", this.NBunsetsus.ToString())); | |
132 | 134 | cprops.Add(new CorpusProperty("#Segments", this.NSegments.ToString())); |
133 | 135 | cprops.Add(new CorpusProperty("#Links", this.NLinks.ToString())); |
134 | 136 | cprops.Add(new CorpusProperty("#Groups", this.NGroups.ToString())); |
@@ -33,7 +33,7 @@ | ||
33 | 33 | |
34 | 34 | private Sentence sen; |
35 | 35 | private Lexeme lexeme; |
36 | - private Segment bunsetsu; | |
36 | + private Bunsetsu bunsetsu; | |
37 | 37 | |
38 | 38 | public static void ResetOrder() |
39 | 39 | { |
@@ -71,6 +71,11 @@ | ||
71 | 71 | get { return lexeme; } |
72 | 72 | set { lexeme = value; } |
73 | 73 | } |
74 | + public virtual Bunsetsu Bunsetsu | |
75 | + { | |
76 | + get { return bunsetsu; } | |
77 | + set { bunsetsu = value; } | |
78 | + } | |
74 | 79 | |
75 | 80 | public virtual int CharLength |
76 | 81 | { |
@@ -10,6 +10,7 @@ | ||
10 | 10 | |
11 | 11 | <many-to-one name="Sen" class="ChaKi.Entity.Corpora.Sentence, ChaKiEntity" column="sentence_id"/> |
12 | 12 | <many-to-one name="Lex" class="ChaKi.Entity.Corpora.Lexeme, ChaKiEntity" column="lexeme_id"/> |
13 | + <many-to-one name="Bunsetsu" class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity" column="bunsetsu_id"/> | |
13 | 14 | <property name="Pos" column="position" type="Int32"/> |
14 | 15 | <property name="StartChar" column="start_char" type="Int32"/> |
15 | 16 | <property name="EndChar" column="end_char" type="Int32"/> |
@@ -16,6 +16,7 @@ | ||
16 | 16 | <many-to-one name="PartOfSpeech" class="ChaKi.Entity.Corpora.PartOfSpeech, ChaKiEntity" column="part_of_speech_id"/> |
17 | 17 | <many-to-one name="CType" class="ChaKi.Entity.Corpora.CType, ChaKiEntity" column="ctype_id"/> |
18 | 18 | <many-to-one name="CForm" class="ChaKi.Entity.Corpora.CForm, ChaKiEntity" column="cform_id"/> |
19 | + <property name="Frequency" column="frequency" type="Int32"/> | |
19 | 20 | </class> |
20 | 21 | |
21 | 22 | </hibernate-mapping> |
@@ -118,6 +118,7 @@ | ||
118 | 118 | |
119 | 119 | private int id; |
120 | 120 | private Dictionary<LP, object> properties; |
121 | + private int frequency; | |
121 | 122 | |
122 | 123 | public virtual int ID |
123 | 124 | { |
@@ -159,6 +160,11 @@ | ||
159 | 160 | get { return properties[LP.CForm] as CForm; } |
160 | 161 | set { properties[LP.CForm] = value; } |
161 | 162 | } |
163 | + public virtual int Frequency | |
164 | + { | |
165 | + get { return this.frequency; } | |
166 | + set { this.frequency = value; } | |
167 | + } | |
162 | 168 | |
163 | 169 | public virtual object GetProperty( LP tag ) |
164 | 170 | { |
@@ -6,11 +6,11 @@ | ||
6 | 6 | { |
7 | 7 | public class Lexicon |
8 | 8 | { |
9 | - private Dictionary<string, Lexeme> m_entries; | |
9 | + private SortedList<string, Lexeme> m_entries; | |
10 | 10 | |
11 | 11 | public Lexicon() |
12 | 12 | { |
13 | - m_entries = new Dictionary<string, Lexeme>(); | |
13 | + m_entries = new SortedList<string, Lexeme>(); | |
14 | 14 | |
15 | 15 | PartsOfSpeech = new Dictionary<string, PartOfSpeech>(); |
16 | 16 | CTypes = new Dictionary<string, CType>(); |
@@ -17,7 +17,7 @@ | ||
17 | 17 | CForms = new Dictionary<string, CForm>(); |
18 | 18 | } |
19 | 19 | |
20 | - public Dictionary<string, Lexeme> Entries | |
20 | + public SortedList<string, Lexeme> Entries | |
21 | 21 | { |
22 | 22 | get { return m_entries; } |
23 | 23 | set { m_entries = value; } |
@@ -38,6 +38,15 @@ | ||
38 | 38 | set { words = value; } |
39 | 39 | } |
40 | 40 | |
41 | + /// <summary> | |
42 | + /// Set of Bunsetsu | |
43 | + /// </summary> | |
44 | + public virtual IList Bunsetsus | |
45 | + { | |
46 | + get { return bunsetsus; } | |
47 | + set { bunsetsus = value; } | |
48 | + } | |
49 | + | |
41 | 50 | public virtual string Text |
42 | 51 | { |
43 | 52 | get { return text; } |
@@ -66,17 +75,118 @@ | ||
66 | 75 | } |
67 | 76 | |
68 | 77 | /// <summary> |
78 | + /// Cabochaフォーマットの文節タグを元にBunsetsuオブジェクトを作成し、 | |
79 | + /// このSentenceに登録する。 | |
80 | + /// すべての文節を作った後、EOSを見た時点でCheckBunsetsusを呼び出して、 | |
81 | + /// 整合を取る必要がある。 | |
82 | + /// </summary> | |
83 | + /// <param name="s"></param> | |
84 | + public virtual Bunsetsu AddBunsetsu(string s) | |
85 | + { | |
86 | + char[] bunsetsuSplitPattern = new char[] { ' ' }; | |
87 | + char[] numberPattern = new char[] { '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' }; | |
88 | + | |
89 | + // "* 0 -D 0/0 0.00000000"の形式の行をパースする | |
90 | + string[] bunsetsuparams = s.Split(bunsetsuSplitPattern); | |
91 | + if (bunsetsuparams.Length < 3) | |
92 | + { | |
93 | + return null; | |
94 | + } | |
95 | + int bunsetsuId = -1; | |
96 | + int depBunsetsuId = -1; | |
97 | + string depType = null; | |
98 | + try | |
99 | + { | |
100 | + bunsetsuId = Int32.Parse(bunsetsuparams[1]); | |
101 | + int pos = bunsetsuparams[2].LastIndexOfAny(numberPattern); | |
102 | + if (pos < 0 || pos + 1 > bunsetsuparams[2].Length - 1) | |
103 | + { | |
104 | + return null; | |
105 | + } | |
106 | + depBunsetsuId = Int32.Parse(bunsetsuparams[2].Substring(0, pos + 1)); | |
107 | + depType = bunsetsuparams[2].Substring(pos + 1, bunsetsuparams[2].Length - pos - 1); | |
108 | + | |
109 | + // パラメータが正しければ、文節オブジェクトを作成し、Setnenceに追加登録 | |
110 | + if (bunsetsuId >= 0 && depType != null) | |
111 | + { | |
112 | + int newsize = Math.Max(bunsetsuId, depBunsetsuId) + 1; | |
113 | + if (this.bunsetsus.Count < newsize) | |
114 | + { | |
115 | + // Bunsetsus配列を拡大 | |
116 | + for (int i = this.bunsetsus.Count; i < newsize; i++) | |
117 | + { | |
118 | + this.bunsetsus.Add(new Bunsetsu()); | |
119 | + } | |
120 | + } | |
121 | + Bunsetsu ph = this.bunsetsus[bunsetsuId] as Bunsetsu; | |
122 | + ph.Pos = bunsetsuId; | |
123 | + ph.Sen = this; | |
124 | + if (depBunsetsuId >= 0) | |
125 | + { | |
126 | + ph.DependsTo = this.bunsetsus[depBunsetsuId] as Bunsetsu; | |
127 | + } | |
128 | + ph.DependsAs = depType; | |
129 | + return ph; | |
130 | + } | |
131 | + } | |
132 | + catch (Exception) | |
133 | + { | |
134 | + return null; | |
135 | + } | |
136 | + return null; | |
137 | + } | |
138 | + | |
139 | + | |
140 | + /// <summary> | |
141 | + /// 文節データの整合性を取る。 | |
142 | + /// 具体的には、 | |
143 | + /// ・文節がまだひとつもなければ、デフォルト文節を1つ作成し、すべてのWordがそれに属するようにする。 | |
144 | + /// さらに | |
145 | + /// ・末尾に空の文節を1つ作成し、DependsTo==nullの文節がそれに係るようにする。 | |
146 | + /// </summary> | |
147 | + public virtual void CheckBunsetsus() | |
148 | + { | |
149 | + if (this.bunsetsus.Count == 0) | |
150 | + { | |
151 | + Bunsetsu defaultBunsetsu = new Bunsetsu(); | |
152 | + defaultBunsetsu.Pos = 0; | |
153 | + defaultBunsetsu.Sen = this; | |
154 | + this.bunsetsus.Add(defaultBunsetsu); | |
155 | + foreach (Word w in this.Words) | |
156 | + { | |
157 | + w.Bunsetsu = defaultBunsetsu; | |
158 | + } | |
159 | + } | |
160 | + Bunsetsu lastBunsetsu = new Bunsetsu(); | |
161 | + lastBunsetsu.Pos = this.bunsetsus.Count; | |
162 | + lastBunsetsu.Sen = this; | |
163 | + this.bunsetsus.Add(lastBunsetsu); | |
164 | + | |
165 | + foreach (Bunsetsu b in this.bunsetsus) | |
166 | + { | |
167 | + if (b != lastBunsetsu && b.DependsTo == null) | |
168 | + { | |
169 | + b.DependsTo = lastBunsetsu; | |
170 | + } | |
171 | + } | |
172 | + | |
173 | + for (int i = 0; i < this.bunsetsus.Count; i++) | |
174 | + { | |
175 | + Debug.Assert(((Bunsetsu)this.bunsetsus[i]).Pos == i); | |
176 | + } | |
177 | + } | |
178 | + | |
179 | + /// <summary> | |
69 | 180 | /// 指定した語の後ろで文節を2つに分離する. |
70 | 181 | /// </summary> |
71 | 182 | /// <param name="bunsetsuPos">文内の文節番号(Bunsetsu.Pos)</param> |
72 | 183 | /// <param name="wordPos">文内の語番号(Word.Pos)</param> |
73 | - public virtual Segment SplitBunsetsu(int bunsetsuPos, int wordPos) | |
184 | + public virtual Bunsetsu SplitBunsetsu(int bunsetsuPos, int wordPos) | |
74 | 185 | { |
75 | -#if false | |
76 | 186 | // 分割対象文節 |
77 | - Segment b_src = null; | |
187 | + Bunsetsu b_src = null; | |
78 | 188 | // 文節番号がbunsetsuPosよりも大きい文節の番号をすべて+1する |
79 | - foreach (Segment b in this.bunsetsus) | |
189 | + foreach (Bunsetsu b in this.bunsetsus) | |
80 | 190 | { |
81 | 191 | if (b.Pos > bunsetsuPos) |
82 | 192 | { |
@@ -89,7 +199,7 @@ | ||
89 | 199 | Trace.Assert( b_src != null ); |
90 | 200 | |
91 | 201 | // 新しい文節を文節番号=bunsetsuPos+1として作成する |
92 | - Segment b_new = new Segment(); | |
202 | + Bunsetsu b_new = new Bunsetsu(); | |
93 | 203 | b_new.Sen = this; |
94 | 204 | b_new.Pos = bunsetsuPos + 1; |
95 | 205 | b_new.DependsTo = b_src.DependsTo; |
@@ -108,9 +218,6 @@ | ||
108 | 218 | |
109 | 219 | // 追加された文節を返す。 |
110 | 220 | return b_new; |
111 | -#else | |
112 | - return null; | |
113 | -#endif | |
114 | 221 | } |
115 | 222 | |
116 | 223 | /// <summary> |
@@ -117,20 +224,19 @@ | ||
117 | 224 | /// 指定した位置の文節とその右の文節を併合する。 |
118 | 225 | /// </summary> |
119 | 226 | /// <param name="bunsetsuPos"></param> |
120 | - public virtual Segment MergeBunsetsu(int bunsetsuPos) | |
227 | + public virtual Bunsetsu MergeBunsetsu(int bunsetsuPos) | |
121 | 228 | { |
122 | -#if false | |
123 | 229 | if (bunsetsuPos < 0 || bunsetsuPos >= this.bunsetsus.Count-1) |
124 | 230 | { |
125 | 231 | return null; |
126 | 232 | } |
127 | - Segment b_merging = (Segment)this.bunsetsus[bunsetsuPos]; | |
128 | - Segment b_merged = (Segment)this.bunsetsus[bunsetsuPos+1]; | |
233 | + Bunsetsu b_merging = (Bunsetsu)this.bunsetsus[bunsetsuPos]; | |
234 | + Bunsetsu b_merged = (Bunsetsu)this.bunsetsus[bunsetsuPos+1]; | |
129 | 235 | |
130 | 236 | // 指定した位置の右にある文節を削除 |
131 | 237 | this.bunsetsus.RemoveAt(bunsetsuPos + 1); |
132 | 238 | // 文節番号がbunsetsuPosよりも大きい文節の番号をすべて-1する |
133 | - foreach (Segment b in this.bunsetsus) | |
239 | + foreach (Bunsetsu b in this.bunsetsus) | |
134 | 240 | { |
135 | 241 | if (b.Pos > bunsetsuPos) |
136 | 242 | { |
@@ -141,7 +247,7 @@ | ||
141 | 247 | // マージして残る文節の係り先を、削除した文節の係り先に変更 |
142 | 248 | b_merging.DependsTo = b_merged.DependsTo; |
143 | 249 | // 削除した文節への係りをすべてマージ先の文節に変更 |
144 | - foreach (Segment b in this.bunsetsus) | |
250 | + foreach (Bunsetsu b in this.bunsetsus) | |
145 | 251 | { |
146 | 252 | if (b.DependsTo == b_merged) |
147 | 253 | { |
@@ -159,9 +265,6 @@ | ||
159 | 265 | |
160 | 266 | // 削除された文節を返す。 |
161 | 267 | return b_merged; |
162 | -#else | |
163 | - return null; | |
164 | -#endif | |
165 | 268 | } |
166 | 269 | } |
167 | 270 | } |
@@ -12,6 +12,11 @@ | ||
12 | 12 | <index column="position"/> |
13 | 13 | <one-to-many class="ChaKi.Entity.Corpora.Word, ChaKiEntity"/> |
14 | 14 | </list> |
15 | + <list name="Bunsetsus" table="bunsetsus" batch-size="20"> | |
16 | + <key column="sentence_id"/> | |
17 | + <index column="position"/> | |
18 | + <one-to-many class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity"/> | |
19 | + </list> | |
15 | 20 | <property name="Text" column="text" type="String"/> |
16 | 21 | <property name="StartChar" column="start_char" type="Int32"/> |
17 | 22 | <property name="EndChar" column="end_char" type="Int32"/> |
@@ -10,7 +10,7 @@ | ||
10 | 10 | <property name="Pos" column="position" type="Int32"/> |
11 | 11 | <many-to-one name="Sen" class="ChaKi.Entity.Corpora.Sentence, ChaKiEntity" column="sentence_id"/> |
12 | 12 | <many-to-one name="DependsTo" class="ChaKi.Entity.Corpora.Bunsetsu, ChaKiEntity" column="dep_bunsetsu_id"/> |
13 | - <property name="DependsAs" column="dep_relation" type="String" length="256"/> | |
13 | + <property name="DependsAs" column="dep_relation" type="String" length="255"/> | |
14 | 14 | </class> |
15 | 15 | |
16 | 16 | </hibernate-mapping> |
@@ -66,6 +66,5 @@ | ||
66 | 66 | private Sentence m_Sen; |
67 | 67 | private Bunsetsu m_DependsTo; |
68 | 68 | private string m_DependsAs; |
69 | - | |
70 | 69 | } |
71 | 70 | } |