I've heard this question a number of times here on Jivespace and I think even a couple times on our intranet (which is called Brewspace) but I've yet to see it documented anywhere, mostly because no one has ever taken the time to explain it to our awesome docs guy Steve (by the way, have you seen the new docs? They're amazing!). I doubt any of you are losing sleep about it, but just in case, here's my simplified, albeit technical, take on things. If you've got a source build handy, I'd encourage you to follow along in your favorite IDE.

 

PopularityDeterminationTask is the class that handles the majority of the work. It runs every 15 minutes (as configured in spring-taskContext.xml, which means you can change it via a plugin in 2.5 if you want) and works closely with ActivityManager.  Every time it runs it does the following things:

  • iterates over the set of containers that exist in Clearspace (communities, projects, social groups and blogs)

  • calculates the popularity of each item in the in-memory copy of activities that activity manager maintains for the current day. The score (or popularity) of each item is calculated by adding together the score of each activity on an item, the scoring is as follows:

    • each comment (blogs and documents) or reply (thread) is given 5 points

    • each modification (documents only) is given 5 points

    • each view is given 1 point

  • calculates the popularity of items in each container stored the database (a popularity score is computed for each item based on the activity that happened that day every night at midnight, this data is stored in the jivePopularity table) for the last seven days. The individual day score is adjusted for each day old that the score is recorded. We call this decay: the computation is done in SQL but if it were done in Java it would look something like this:

Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, -daysAgo);
Date now = new Date();
Date nDaysAgo = c.getTime();
long dateDiff = now.getTime() - nDaysAgo.getTime();
long dateAdjustment = dateDiff / 86400000; 
long decayedScore = score / (1 + dateAdjustment);
  • add the results of step 2 and step 3 together. So for example, let's say I published a blog post 2 months ago and through some sort of magic, it got 3 comments every day for the last 2 months (and it's already received 2 comments today that haven't been archived to the jivePopularity table). We only take into account the popularity score for the last seven days so the total score is going to be the sum of the following scores:

     

    Date

    Number of Comments

    Recorded Score

    Score With Decay

    6/5/2008 (today)

    3

    15

    15

    6/4/2008

    3

    15

    7

    6/3/2008

    3

    15

    5

    6/2/2008

    3

    15

    3

    6/1/2008

    3

    15

    3

    5/31/2008

    3

    15

    2

    5/30/2008

    3

    15

    2

    Total Score

    37

     

  • Finally, each item is added to a SortedSet and then copied back to ActivityManager, where it lives until the next time popularity is calculated fifteen minutes later.

 

So when you see a widget that shows the most popular items for a given community / space, project, social group or blog, you're getting the n items who have the highest combined score, which is a combination of comments, replies, edits and views, decayed over the last seven days. ¿Comprende?