/// <summary> /// Compute statistics against basis /// </summary> public void Parametrize(ResultSummary groundThruth) { if ((this.QueryList.Count != groundThruth.QueryList.Count) || this.QueriesName != groundThruth.QueriesName) { throw new ArgumentException ("ERROR: QUERY SOURCES DOESN'T MATCH!!"); } double count = this.QueryList.Count; var recall = 0.0; for (int i = 0; i < count; ++i) { recall += Query.Recall (groundThruth.QueryList [i].Result, this.QueryList [i].Result); } this.Parametrized ["Recall"] = recall / count; this.Parametrized ["Speedup"] = groundThruth.SearchTime / this.SearchTime; if (groundThruth.SearchCostInternal > 0) { this.Parametrized ["SearchCostInternal"] = this.SearchCostInternal / groundThruth.SearchCostInternal; } else { this.Parametrized ["SearchCostInternal"] = 0.0; } if (groundThruth.SearchCostTotal > 0) { this.Parametrized ["SearchCostTotal"] = this.SearchCostTotal / groundThruth.SearchCostTotal; } else { this.Parametrized ["SearchCostTotal"] = 0.0; } this.Parametrized ["ProximityRatio"] = this.CoveringRadius / groundThruth.CoveringRadius; this.Parametrized ["Memory"] = 0; this.Parametrized ["ConstructionCostTime"] = 0; this.Parametrized ["ConstructionCostDistances"] = 0; int pop = 0; foreach (var q in this.QueryList) { pop += q.Result.Count; } this.Parametrized ["QueryPopulation"] = pop / (double) this.QueryList.Count; if (File.Exists (this.IndexName)) { using (var f = File.OpenRead(this.IndexName)) { this.Parametrized ["Memory"] = f.Length; } } if (File.Exists (this.IndexName + ".construction-time.json")) { var txt = File.ReadAllText (this.IndexName + ".construction-time.json"); try { var msg = JsonConvert.DeserializeObject<Dictionary<string, object>> (txt); this.Parametrized ["ConstructionCostTime"] = msg["Seconds"]; this.Parametrized ["ConstructionCostDistances"] = msg["Distances"]; } catch (Newtonsoft.Json.JsonReaderException) { Console.WriteLine ("Ignoring construction-time information. Old construction-time format?"); } } }
/// <summary> /// Search shell (not interactive at this level) /// </summary> public static void Search(Index index, IEnumerable<CommandQuery> qReader, ShellSearchOptions searchOps) { var summary = new ResultSummary () { ResultName = searchOps.ResultName, IndexName = searchOps.IndexName, QueriesName = searchOps.QueryName }; int qid = 0; long totaltime = 0; SearchCost totalCost = new SearchCost (0, 0); foreach (CommandQuery qItem in qReader) { long tstart = DateTime.Now.Ticks; SearchCost startCost = index.Cost; IResult res; var qobj = qItem.QObj; if (qobj == null) { qobj = index.DB.Parse (qItem.QRaw); } if (qItem.QTypeIsRange) { res = index.SearchRange (qobj, qItem.QArg); } else { res = index.SearchKNN (qobj, (int)qItem.QArg); } var qraw = qItem.QRaw; SearchCost finalCost = index.Cost; finalCost.Internal -= startCost.Internal; finalCost.Total -= startCost.Total; totalCost.Internal += finalCost.Internal; totalCost.Total += finalCost.Total; long time = DateTime.Now.Ticks - tstart; totaltime += time; var query = new Query () { QueryID = qid, QueryType = qItem.EncodeQTypeQArgInSign(), QueryRaw = qraw, SearchCostTotal = finalCost.Total, SearchCostInternal = finalCost.Internal, SearchTime = (new TimeSpan(time)).TotalSeconds, Result = new List<ItemPair>(res) }; Console.WriteLine ("----- QueryID: {0}, QueryType: {1} -----", query.QueryID, query.QueryType); if (res.Count == 0) { Console.WriteLine ("- results> empty result set"); } else { Console.WriteLine ("- results> count: {0}, first-dist: {1}, last-dist: {2}", res.Count, res.First.Dist, res.CoveringRadius); } Console.WriteLine ("- search-time: {0}, cost-internal-distances: {1}, cost-total-distances: {2}", query.SearchTime, query.SearchCostInternal, query.SearchCostTotal); Console.WriteLine ("- index: {0}, db: {1}, result: {2}", index, Path.GetFileName(index.DB.Name), Path.GetFileName(searchOps.ResultName)); summary.Add (query); qid++; } summary.ComputeSummary (); if (searchOps.ResultName != null) { File.WriteAllText (searchOps.ResultName, JsonConvert.SerializeObject (summary, Formatting.Indented)); } Console.WriteLine ("Number queries: {0}", qid); Console.WriteLine ("Average total-numdists: {0}", (totalCost.Total + 0.0) / qid); Console.WriteLine ("Average internal-distances: {0}", (totalCost.Internal + 0.0) / qid); Console.WriteLine ("Average external-distances: {0}", (totalCost.Total - totalCost.Internal + 0.0) / qid); Console.WriteLine ("Total search time: {0}", (new TimeSpan (totaltime)).TotalSeconds); Console.WriteLine ("Average search time: {0}", (new TimeSpan (totaltime / qid)).TotalSeconds); }