static void CollectChains(SentenceConstruct sen, SqliteCommand cmd) { while (sen.Continue) { string chain = sen.LatestChain(); // Seems like Add is slightly faster than AddWithValue, although the difference is so small it only // makes sense to use it in this loop, where it can get called 10's of thousands of times. cmd.Parameters.Add("@Chain", DbType.String).Value = chain; var followUp = (string)cmd.ExecuteScalar(); // If the chain couldn't be found (followUp is null) or if the chain is an ending chain (followUp is // empty) stop collecting chains. if (!string.IsNullOrEmpty(followUp)) { sen.ModeAdd(followUp); } else { return; } } }
IEnumerable <Sentence> Builder(BuilderVectors v) { // Copies out the volatile field, so we have a consistent MaxWords while building. var words = new SentenceConstruct(Order, MaxWords); using (var reader = v.StartingChains.ExecuteReader()) { while (reader.Read()) { string backward = reader.GetString(0); string chain = reader.GetString(1); string forward = reader.GetString(2); words.Set(chain); if (backward != string.Empty) { // Backward search. words.PrependMode(); words.ModeAdd(backward); CollectChains(words, v.BackwardSearch); } if (forward != string.Empty && words.Continue) { // Forward search. words.AppendMode(); words.ModeAdd(forward); CollectChains(words, v.ForwardSearch); } var segment = words.CurrentSegment(); long[] wordCounts = WordCount(segment, v.WordCount); yield return(new Sentence(segment, wordCounts)); } } }