public CsvMetadata Clone() { CsvMetadata rv = new CsvMetadata(); rv.Values = Values; return(rv); }
public CsvStats(CsvStats sourceCsvStats, string [] statNamesToFilter = null) { Stats = new Dictionary <string, StatSamples>(); Events = new List <CsvEvent>(); if (statNamesToFilter != null) { foreach (string statName in statNamesToFilter) { List <StatSamples> stats = sourceCsvStats.GetStatsMatchingString(statName); foreach (StatSamples sourceStat in stats) { string key = sourceStat.Name.ToLower(); if (!Stats.ContainsKey(key)) { Stats.Add(key, new StatSamples(sourceStat)); } } } } else { foreach (StatSamples sourceStat in sourceCsvStats.Stats.Values) { AddStat(new StatSamples(sourceStat)); } } foreach (CsvEvent ev in sourceCsvStats.Events) { Events.Add(new CsvEvent(ev)); } if (sourceCsvStats.metaData != null) { metaData = new CsvMetadata(sourceCsvStats.metaData); } }
public void CombineAndValidate(CsvMetadata comparisonMetadata) { List <string> valuesDontMatchKeys = new List <string>(); foreach (KeyValuePair <string, string> pair in Values) { bool bMatch = false; if (comparisonMetadata.Values.ContainsKey(pair.Key)) { if (comparisonMetadata.Values[pair.Key] == pair.Value) { bMatch = true; } } if (!bMatch) { valuesDontMatchKeys.Add(pair.Key); break; } } foreach (string key in valuesDontMatchKeys) { Values[key] = "[" + key + " doesn't match!]"; } }
public CsvMetadata(CsvMetadata source) { Values = new Dictionary <string, string>(); List <KeyValuePair <string, string> > pairList = source.Values.ToList(); foreach (KeyValuePair <string, string> pair in pairList) { Values.Add(pair.Key, pair.Value); } }
public static bool Matches(CsvMetadata a, CsvMetadata b) { if (a == null && b == null) { return(true); } if (a == null) { return(false); } if (b == null) { return(false); } if (a.Values.Count != b.Values.Count) { return(false); } foreach (KeyValuePair <string, string> pair in a.Values) { bool bMatch = false; // if (pair.Key != "deviceprofile") { if (b.Values.ContainsKey(pair.Key)) { if (b.Values[pair.Key] == pair.Value) { bMatch = true; } } if (!bMatch) { return(false); } } } return(true); }
public static bool DoesMetadataMatchFilter(CsvMetadata metadata, string metadataFilterString) { string[] keyValuePairStrs = metadataFilterString.Split(','); foreach (string keyValuePairStr in keyValuePairStrs) { string[] keyValue = keyValuePairStr.Split('='); if (keyValue.Length != 2) { return(false); } string key = keyValue[0].ToLower(); if (!metadata.Values.ContainsKey(key)) { return(false); } if (metadata.Values[key].ToLower() != keyValue[1].ToLower()) { return(false); } } return(true); }
public static CsvStats ReadCSVFromLines(string[] linesArray, string[] statNames, int numRowsToSkip = 0, bool skipReadingData = false) { List <string> lines = linesArray.ToList(); // Check if we have any metadata bool bHasMetaData = LineIsMetadata(lines.Last()); CsvMetadata metaData = null; // Add the metadata to the stats collection if (bHasMetaData) { string[] lastLine = lines.Last().Split(','); metaData = new CsvMetadata(lastLine); // New CSVs from the csv profiler have a header row at the end of the file, // since the profiler writes out the file incrementally. if ("1" == metaData.GetValue("hasheaderrowatend", null)) { // Swap the header row for the one at the end of the file, // then remove the end one. lines[0] = lines[lines.Count - 2]; lines.RemoveAt(lines.Count - 2); } } if (numRowsToSkip > 0) { lines.RemoveRange(0, numRowsToSkip); } string[] headings = lines[0].Split(','); if (lines.Count > 2 && lines[lines.Count - 1] == "\"") { lines[lines.Count - 2] += lines[lines.Count - 1]; lines.RemoveAt(lines.Count - 1); } if (skipReadingData) { int dataLineCount = bHasMetaData ? lines.Count - 2 : lines.Count - 1; lines.RemoveRange(1, dataLineCount); } // Get the list of lower case stat names, expanding wildcards string[] statNamesLowercase = null; if (statNames != null) { statNamesLowercase = statNames.Select(s => s.ToLowerInvariant()).ToArray(); { // Expand the list of stat names based on the wildcards and the headers. We do this here to make sorting simpler HashSet <string> newStatNamesLowercase = new HashSet <string>(); foreach (string statname in statNamesLowercase) { if (statname.EndsWith("*")) { int index = statname.LastIndexOf('*'); string prefix = statname.Substring(0, index); // Expand all the stat names foreach (string headingStat in headings) { if (headingStat.ToLower().StartsWith(prefix)) { newStatNamesLowercase.Add(headingStat.ToLower()); } } } else { newStatNamesLowercase.Add(statname); } } statNamesLowercase = newStatNamesLowercase.ToArray(); } } // First line is headings, last line contains build info int numSamples = lines.Count - (bHasMetaData ? 2 : 1); // Create the stats int eventHeadingIndex = -1; StatSamples[] stats = new StatSamples[headings.Length]; for (int i = 0; i < headings.Length; i++) { string heading = headings[i].Trim(); if (heading == "") { continue; } // find the events column (if there is one) else if (heading.ToLower() == "events") { eventHeadingIndex = i; } else if (statNamesLowercase == null || statNamesLowercase.Contains(heading.ToLower())) { stats[i] = new StatSamples(heading, numSamples); } } List <CsvEvent> FilteredEvents = new List <CsvEvent>(); if (!skipReadingData) { string[] eventStrings = new string[numSamples]; // for (int i = 1; i < numSamples + 1; i++) Parallel.For(1, numSamples + 1, i => { int sampleIndex = i - 1; int statIndex = 0; string line = lines[i] + "\n"; for (int j = 0; j < line.Length; j++) { // Note: we check statIndex<stats.length here in case of truncated CSVs if (statIndex < stats.Length && stats[statIndex] != null) { // Read the stat float value = 0.0f; // Skip whitespace while (line[j] == ' ') { j++; } bool negative = false; if (line[j] == '-') { negative = true; j++; } // Read the nonfractional part of the number int num = 0; while (line[j] >= '0' && line[j] <= '9') { num *= 10; num += line[j] - '0'; j++; } value = (float)num; if (line[j] == '.') { // read fractional part num = 0; j++; float multiplier = 0.1f; while (line[j] >= '0' && line[j] <= '9') { value += (float)(line[j] - '0') * multiplier; j++; multiplier *= 0.1f; } } if (negative) { value = -value; } stats[statIndex].samples[sampleIndex] = value; // Skip everything else until the next newline or comma while (line[j] != ',' && line[j] != '\n') { j++; } } else { // Skip parsing int startJ = j; while (line[j] != ',' && line[j] != '\n') { j++; } if (statIndex == eventHeadingIndex) { eventStrings[sampleIndex] = line.Substring(startJ, j - startJ); } } statIndex++; } } ); // Needed by parallel for // Read events for (int i = 0; i < eventStrings.Length; i++) { string eventString = eventStrings[i]; if (!string.IsNullOrEmpty(eventString)) { string[] Events = eventString.Split(';'); foreach (string EventString in Events) { if (EventString.Length > 0) { CsvEvent ev = new CsvEvent(); ev.Frame = i; ev.Name = EventString; FilteredEvents.Add(ev); } } } } } // Make sure the stat ordering matches the order they're passed in CsvStats csvStats = new CsvStats(); if (statNamesLowercase != null) { CsvStats unorderedCsvStats = new CsvStats(); foreach (StatSamples statSamples in stats) { if (statSamples != null) { // Combine stats if we find a duplicate if (unorderedCsvStats.Stats.ContainsKey(statSamples.Name.ToLower())) { StatSamples existingStat = unorderedCsvStats.GetStat(statSamples.Name); for (int i = 0; i < statSamples.samples.Count; i++) { existingStat.samples[i] += statSamples.samples[i]; } } else { unorderedCsvStats.AddStat(statSamples); } } } foreach (string statName in statNamesLowercase) { StatSamples stat = unorderedCsvStats.GetStat(statName); if (stat != null) { csvStats.AddStat(stat); } } } else { int c = 0; foreach (StatSamples statSamples in stats) { c++; if (statSamples != null) { if (csvStats.Stats.ContainsKey(statSamples.Name.ToLower())) { // Combine stats if we find a duplicate StatSamples existingStat = csvStats.GetStat(statSamples.Name); for (int i = 0; i < statSamples.samples.Count; i++) { existingStat.samples[i] += statSamples.samples[i]; } } else { csvStats.AddStat(statSamples); } } } } // Compute averages foreach (StatSamples stat in csvStats.Stats.Values.ToArray()) { stat.ComputeAverageAndTotal(); } csvStats.metaData = metaData; csvStats.Events = FilteredEvents; return(csvStats); }