public static IMatchSet operator &(IMatchSet a, IMatchSet b) { if (b == null) { return(a); } if (a == null) { return(b); } MatchSet r = new MatchSet(); if (a.Count < b.Count) { foreach (EntryId n in a) { if (b.Contains(n)) { r.Add(n); } } } else { foreach (EntryId n in b) { if (a.Contains(n)) { r.Add(n); } } } return(r); }
/// <summary> /// Finds all matches from any of the provided string keys. /// </summary> /// <param name="stringKeys">set of string keys to find in index</param> /// <param name="errors">Place to add error messages</param> /// <returns>match set</returns> public MatchSet Matches(List <string> stringKeys, List <string> errors = null) { MatchSet matches = new MatchSet(); foreach (string v in stringKeys) { matches.Or(tIndex[v]); } return(matches); }
/// <summary> /// Finds all matches from any of the provided number keys. /// </summary> /// <param name="numberKeys">set of number keys to find in index</param> /// <param name="errors">Place to add error messages</param> /// <returns>match set</returns> public IMatchSet Matches(List <UInt64> numberKeys, List <string> errors = null) { MatchSet matches = new MatchSet(); foreach (UInt64 v in numberKeys) { matches.Or(nIndex[v]); } return(matches); }
/// <summary> /// Gets the key in the index that is the exact number provided, or returns an empty list. /// </summary> /// <param name="token">Key description token this is a hexadecimal number</param> /// <param name="errors">Place to add error messages</param> /// <returns>a list of unique number keys</returns> List <UInt64> GetExactNumberKey(string token, List <string> errors = null) { IMatchSet matches = new MatchSet(); UInt64 address = UInt64.Parse(token, System.Globalization.NumberStyles.HexNumber); List <UInt64> list = new List <ulong>(); if (nIndex.ContainsKey(address)) { list.Add(address); } if (list.Count() == 0) { if (errors != null) { errors.Add(string.Format("number {0} not found in index ", token)); } } return(list); }
public static IMatchSet operator |(IMatchSet a, IMatchSet b) { if (b == null) { return(a); } if (a == null) { return(b); } MatchSet r = new MatchSet(); foreach (EntryId n in a) { r.Add(n); } foreach (EntryId n in b) { r.Add(n); } return(r); }
/// <summary> /// add a log entry to the index /// /// This method parse the entryString into Key tokens. /// A number is determined when an alphanumeric sequence of characters is all hexidecimal characters. /// 'badfeed' is a number, 'badfood' is not. /// The rest of the string is split into substrings, delimited by any number or any delimiter character. /// Each substring is converted into a valid key (trimming, and using '_' for spaces, etc.) /// Each string key and number key is added to the index to help find this entry. /// </summary> /// <param name="entryId">the index into the log</param> /// <param name="entryString">The string that describes the log entry</param> public void AddLogEntry(int entryId, string entryString) { count = Math.Max(count, entryId + 1); List <UInt64> numberKeys = new List <ulong>(); List <string> stringKeys = new List <string>(); states state = states.linenum; int lastc = 0; char prev = '0'; for (int i = 0; i < entryString.Count(); i++) { char c = entryString[i]; switch (state) { case states.linenum: if (c == ',') { state = states.text; lastc = i + 1; } break; case states.text: bool isStartOfNumber = false; if (c == ' ' && i == lastc) { lastc++; } if (IsHex(c) && !IsAlphaNum(prev)) { isStartOfNumber = true; for (int j = i + 1; j < entryString.Length; j++) { char c2 = entryString[j]; if (IsHex(c2)) { // still ok. } else if (c2 >= 'a' && c2 <= 'z') { isStartOfNumber = false; break; } else { break; } } } if (isStartOfNumber) { if (i > lastc) { var p1 = entryString.Substring(lastc, i - lastc); stringKeys.Add(p1); } lastc = i; state = states.number; } break; case states.number: if (!IsHex(c)) { if (i > lastc) { string num = entryString.Substring(lastc, i - lastc); numberKeys.Add(UInt64.Parse(num, System.Globalization.NumberStyles.HexNumber)); } lastc = i; state = states.text; } break; } prev = c; } // cleanup switch (state) { case states.linenum: break; case states.text: stringKeys.Add(entryString.Substring(lastc)); break; case states.number: { string num = entryString.Substring(lastc); numberKeys.Add(UInt64.Parse(num, System.Globalization.NumberStyles.HexNumber)); } break; } // add stringkeys to index foreach (string s in stringKeys) { string[] parts = s.Split(delims); foreach (string part in parts) { string p = IndexableString(part); if (p == "") { continue; } lock (tIndex) { if (!tIndex.ContainsKey(p)) { tIndex[p] = new MatchSet(); } } lock (tIndex[p]) { tIndex[p].Add(new EntryId(entryId)); } } } // add number keys to index foreach (UInt64 n in numberKeys) { lock (nIndex) { if (!nIndex.ContainsKey(n)) { nIndex[n] = new MatchSet(); } nIndex[n].Add(new EntryId(entryId)); } } }