aboutsummaryrefslogtreecommitdiffstats
path: root/background_scripts
diff options
context:
space:
mode:
authorPhil Crosby2012-06-03 00:27:46 -0700
committerPhil Crosby2012-06-03 16:52:32 -0700
commit51f197952208701542eef60b353f248e5b9c6054 (patch)
tree34109317322b81129a93ec8cbf8b019fad0c2877 /background_scripts
parent2cbb4961ce60d75c1535ad65ede5ca74db254cb3 (diff)
downloadvimium-51f197952208701542eef60b353f248e5b9c6054.tar.bz2
Implement ranking, and use recency when ranking history entries
One major change between this and the previous implementation is that all scores are between [0, 1] and "1" means most relevant.
Diffstat (limited to 'background_scripts')
-rw-r--r--background_scripts/completion.coffee49
1 files changed, 42 insertions, 7 deletions
diff --git a/background_scripts/completion.coffee b/background_scripts/completion.coffee
index 5cc36227..2f6053b8 100644
--- a/background_scripts/completion.coffee
+++ b/background_scripts/completion.coffee
@@ -1,6 +1,6 @@
class Suggestion
# - type: one of [bookmark, history, tab].
- constructor: (@queryTerms, @type, @url, @title) ->
+ constructor: (@queryTerms, @type, @url, @title, @computeRelevancyFunction, @extraRelevancyData) ->
generateHtml: ->
@html ||=
@@ -30,9 +30,7 @@ class Suggestion
Suggestion.escapeRegExp ||= /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g
new RegExp(string.replace(Suggestion.escapeRegExp, "\\$&"), "i")
- computeRelevancy: ->
- # TODO(philc):
- 1
+ computeRelevancy: -> @relevancy = @computeRelevancyFunction(@queryTerms, this)
class BookmarkCompleter
currentSearch: null
@@ -49,7 +47,7 @@ class BookmarkCompleter
results = @bookmarks.filter (bookmark) =>
RankingUtils.matches(@currentSearch.queryTerms, bookmark.url, bookmark.title)
suggestions = results.map (bookmark) =>
- new Suggestion(@currentSearch.queryTerms, "bookmark", bookmark.url, bookmark.title)
+ new Suggestion(@currentSearch.queryTerms, "bookmark", bookmark.url, bookmark.title, @computeRelevancy)
onComplete = @currentSearch.onComplete
@currentSearch = null
onComplete(suggestions)
@@ -68,18 +66,35 @@ class BookmarkCompleter
bookmark = toVisit.shift()
results.push(bookmark)
toVisit.push.apply(toVisit, bookmark.children) if (bookmark.children)
-
results
+ computeRelevancy: (queryTerms, suggestion) ->
+ RankingUtils.wordRelevancy(queryTerms, suggestion.url, suggestion.title)
+
class HistoryCompleter
filter: (queryTerms, onComplete) ->
@currentSearch = { queryTerms: @queryTerms, onComplete: @onComplete }
results = []
HistoryCache.use (history) ->
results = history.filter (entry) -> RankingUtils.matches(queryTerms, entry.url, entry.title)
- suggestions = results.map (entry) => new Suggestion(queryTerms, "history", entry.url, entry.title)
+ suggestions = results.map (entry) =>
+ new Suggestion(queryTerms, "history", entry.url, entry.title, @computeRelevancy, entry)
onComplete(suggestions)
+ computeRelevancy: (queryTerms, suggestion) ->
+ @oneMonthAgo ||= 1000 * 60 * 60 * 24 * 30
+ historyEntry = suggestion.extraRelevancyData
+ recency = Date.now() - historyEntry.lastVisitTime
+ recencyDifference = Math.max(0, @oneMonthAgo - recency) / @oneMonthAgo
+
+ # recencyScore is between [0, 1]. It is 1 when recenyDifference is 0. This qudratic equation will
+ # incresingly discount older history entries.
+ recencyScore = recencyDifference * recencyDifference * recencyDifference
+
+ wordRelevancy = RankingUtils.wordRelevancy(queryTerms, suggestion.url, suggestion.title)
+ # Average out the word score and the recency. Recency has the ability to pull the score up, but not down.
+ score = (wordRelevancy + Math.max(recencyScore, wordRelevancy)) / 2
+
refresh: ->
class MultiCompleter
@@ -116,6 +131,26 @@ RankingUtils =
return false unless title.indexOf(term) >= 0 || url.indexOf(term) >= 0
true
+ # Returns a number between [0, 1] indicating how often the query terms appear in the url and title.
+ wordRelevancy: (queryTerms, url, title) ->
+ queryLength = 0
+ urlScore = 0.0
+ titleScore = 0.0
+ for term in queryTerms
+ queryLength += term.length
+ urlScore += 1 if url.indexOf(term) >= 0
+ titleScore += 1 if title.indexOf(term) >= 0
+ urlScore = urlScore / queryTerms.length
+ urlScore = urlScore * RankingUtils.normalizeDifference(queryLength, url.length)
+ titleScore = titleScore / queryTerms.length
+ titleScore = titleScore * RankingUtils.normalizeDifference(queryLength, title.length)
+ (urlScore + titleScore) / 2
+
+ # Takes the difference of two numbers and returns a number between [0, 1] (the percentage difference).
+ normalizeDifference: (a, b) ->
+ max = Math.max(a, b)
+ (max - Math.abs(a - b)) / max
+
# Provides cached access to Chrome's history.
HistoryCache =
size: 20000