public AhoKorasik_Parallel(List <char> alphabet = null) { root = new Node_Parallel(); this.alphabet = alphabet; maxWordLength = 0; IsPreparable = alphabet != null && alphabet.Count != 0; }
public Node_Parallel(Node_Parallel parent = null, char charToParent = (char)0) { Sons = new ConcurrentDictionary <char, Node_Parallel>(); Transitions = new ConcurrentDictionary <char, Node_Parallel>(); IsTerminal = false; SuffLink = null; PressedSuffixLink = null; Parent = parent; CharToParent = charToParent; Locker = new object(); }
private Node_Parallel nonLockedGetPressedSuffixLink() { if (PressedSuffixLink == null) { if (nonLockedGetSuffLink().IsTerminal || nonLockedGetSuffLink().Parent == null) { PressedSuffixLink = nonLockedGetSuffLink(); } else { PressedSuffixLink = nonLockedGetSuffLink().GetPressedSuffixLink(); } } return(PressedSuffixLink); }
// almost same as FindInParfOfText private Task <bool> FindInParfOfText_Prepared(string text, int begin, int end) { return(Task.Run(() => { Node_Parallel current = root; for (int i = begin; i < end; ++i) { current = current.Transitions[text[i]]; if (current.IsTerminal || current.PressedSuffixLink != root) { return true; } } return false; })); }
private Task PrepareTransition(Node_Parallel current) { return(Task.Run(() => { // prepering suffix link if (current == root || current.Parent == root) { current.SuffLink = root; } else { current.SuffLink = current.Parent.SuffLink.Transitions[current.CharToParent]; } // preparing pressed suffix link if (current.SuffLink.IsTerminal || current.SuffLink == root) { current.PressedSuffixLink = current.SuffLink; } else { current.PressedSuffixLink = current.SuffLink.PressedSuffixLink; } // prepering suffix transitions foreach (char letter in alphabet) { //Console.WriteLine("ForEach " + Thread.CurrentThread.ManagedThreadId); if (current.Sons.ContainsKey(letter)) { current.Transitions[letter] = current.Sons[letter]; } else if (current == root) { current.Transitions[letter] = current; } else { current.Transitions[letter] = current.SuffLink.Transitions[letter]; } } ; })); }
private Node_Parallel nonLockedGetSuffLink() { if (SuffLink == null) { if (Parent == null) { SuffLink = this; } else if (Parent.Parent == null) { SuffLink = Parent; } else { SuffLink = Parent.GetSuffLink().GetTransition(CharToParent); } } return(SuffLink); }
public Task AddString(string str) { maxWordLength = Math.Max(maxWordLength, str.Length); return(Task.Run(() => { Node_Parallel current = root; for (int i = 0; i < str.Length; ++i) { lock (current.Locker) { if (!current.Sons.ContainsKey(str[i])) { current.Sons[str[i]] = new Node_Parallel(current, str[i]); } current = current.Sons[str[i]]; } } current.IsTerminal = true; })); }
// almost same as IsOneOfStringsInText public bool IsOneOfStringsInText_Prepared(string text) { int maxThreadNumber = 3; int possibleFullParts = (int)Math.Ceiling((double)text.Length / maxWordLength); if (possibleFullParts >= 3) { int divideToParts = Math.Min(possibleFullParts - 1, maxThreadNumber); int subpartsInEachPart = (int)Math.Ceiling((double)(possibleFullParts + divideToParts - 1) / divideToParts); Task <bool>[] t = new Task <bool> [divideToParts]; for (int i = 0; i < divideToParts; ++i) { t[i] = FindInParfOfText_Prepared( text, i * (subpartsInEachPart - 1) * maxWordLength, Math.Min(text.Length, (i + 1) * (subpartsInEachPart - 1) * maxWordLength + maxWordLength) ); } Task.WaitAll(t); return(t.Any(x => x.Result == true)); } else { Node_Parallel current = root; for (int i = 0; i < text.Length; ++i) { current = current.Transitions[text[i]]; if (current.IsTerminal || current.PressedSuffixLink != root) { return(true); } } return(false); } }