public override void IncreaseRelevance(Item element, string match, Item other) { RelevanceRecord rec; if (element == null) { throw new ArgumentNullException("element"); } match = match ?? ""; newest_hit = DateTime.Now; if (!hits.TryGetValue(element.UniqueId, out rec)) { rec = new RelevanceRecord(element); hits [element.UniqueId] = rec; } rec.Hits++; rec.LastHit = DateTime.Now; if (other == null) { rec.FirstPaneHits++; } if (0 < match.Length) { rec.AddFirstChar(match [0]); } UpdateMaxHits(rec, element); }
void UpdateMaxHits(RelevanceRecord rec, Item e) { if (e.IsAction()) { max_action_hits = Math.Max(max_action_hits, rec.Hits); } else { max_item_hits = Math.Max(max_item_hits, rec.Hits); } }
public override float GetRelevance(Item e, string match, Item other) { RelevanceRecord rec; bool isAction; float relevance = 0f, age = 0f, score = 0f; string name = e.Safe.Name; if (!hits.TryGetValue(e.UniqueId, out rec)) { rec = new RelevanceRecord(e); } isAction = e.IsAction(); // Get string similarity score. score = StringScoreForAbbreviation(name, match); if (score == 0f) { return(0f); } // Pin some actions to top. // TODO Remove this when relevance is refactored and improved. if (other != null && (e is OpenAction || e is RunAction || e is OpenUrlAction)) { return(1f); } // We must give a base, non-zero relevance to make scoring rules take // effect. We scale by length so that if two objects have default // relevance, the object with the shorter name comes first. Objects // with shorter names tend to be simpler, and more often what the // user wants (e.g. "Jay-Z" vs "Jay-Z feat. The Roots"). relevance = DefaultRelevance / Math.Max(1, name.Length); if (0 < rec.Hits) { // On a scale of 0 (new) to 1 (old), how old is the item? age = (float)(newest_hit - rec.LastHit).TotalSeconds / (float)(newest_hit - oldest_hit).TotalSeconds; if (rec.IsRelevantForMatch(match)) { relevance = (float)rec.Hits / (float)(isAction ? max_action_hits : max_item_hits); } } else { // Objects we don't know about are treated as old. age = DefaultAge; // Give the most popular items a leg up if (typeof(IApplicationItem).IsInstanceOfType(e)) { relevance *= 2; } } // Newer objects (age -> 0) get scaled by factor -> 1. // Older objects (age -> 1) get scaled by factor -> .5. relevance *= 1f - age / 2f; if (isAction) { SafeAct action = e.AsAction().Safe; // We penalize actions, but only if they're not used in the first pane // often. if (rec.FirstPaneHits < 3) { relevance *= 0.8f; } // Penalize actions that require modifier items. if (!action.ModifierItemsOptional) { relevance *= 0.8f; } } if (typeof(ItemSourceItemSource.ItemSourceItem).IsInstanceOfType(e)) { relevance *= 0.4f; } return(relevance * 0.30f + score * 0.70f); }