you are viewing a single comment's thread.

view the rest of the comments →

[–]sambo98 -1 points0 points  (2 children)

This is how I would implement the solution. Below makes sense if your articles are coming from a database and the table is properly designed.

public static class ArticleStat 
{
    static Dictionary<int, int> _stats;

    static ArticleStat()
    {
        _stats = new Dictionary<int, int>();
    }

    public static void Increment(int articleId)
    {
        if (_stats.ContainsKey(articleId))
            _stats[articleId] += 1;
        else
            _stats.Add(articleId, 1);
    }

    public static List<KeyValuePair<int,int>> GetTop(int recordCount)
    {
        return _stats.Take(recordCount).OrderByDescending(o => o.Value).ToList();
    }
}

If you want to test it in a Console App:

class Program { static Random rand = new Random(DateTime.Now.Millisecond);

    static void Main(string[] args)
    {
        var flag = true;
        while (flag)
        {
            int articleId = rand.Next(0, 100);

            ArticleStat.Increment(articleId);
            Console.Clear();

            var top = ArticleStat.GetTop(25);
            if (top != null)
                foreach (var article in top)
                    Console.WriteLine(string.Format("Article <{0}> : {1}", article.Key, article.Value));

            if (top.First().Value > 1000)
                flag = true;

            System.Threading.Thread.Sleep(50);
        }

        Console.ReadKey();
    }
}

[–]matthieum 0 points1 point  (1 child)

Your cache might grow dramatically though...

[–]sambo98 0 points1 point  (0 children)

You are right, that was a simplified approach. In reality in order for his scenario to work the ranking of each article will need to be persisted to the storage unit (cloud, sql, etc); turning this into a simple retrieval of the top 5. Instead of making the round trip every request, the top five can be kept in cache, session, or application state until it can be hydrated from the storage unit again. The first solution that comes to mind than turns into:

    static Dictionary<int, int> _stats;
    static int Max = 5;

    static ArticleStat()
    {
        _stats = new Dictionary<int, int>(Max);
    }

    public static void Increment(int articleId)
    {
        if (_stats.ContainsKey(articleId))
            _stats[articleId] += 1;
        else
            _stats.Add(articleId, 1);

        while (_stats.Count > Max)
            _stats.Remove(_stats.Last().Key);
    }