Sobes.tech
Senior

/* You are a writer, running your mini blog and publishing articles there. Your blog users (readers), after authorization, can view/read them. Implement functionality to count unique views per day for each article. Functional requirements: - Today's statistics: The author can see how many unique users viewed their article today (data is accumulated in real-time). - Past days' statistics: The author can see statistics for any past day (for yesterday). Technical constraints and conditions: - The application runs on 1 server (1 pod) - Storage in memory - Time in UTC0 */

sobes.tech AI

Answer from AI

To count unique article views per day with data stored in memory and a single server, you can use the following structure:

  • For each day (by UTC date), store a map: map[articleID]map[userID]bool, where keys are article IDs and user IDs.
  • When an authorized user views an article, add the userID to the map for the corresponding article and current date.
  • To get statistics for today or the previous day, count the length of the inner user map for the article.

Example in Go:

 type Stats struct {
    mu sync.RWMutex
    data map[string]map[string]map[string]bool // date -> articleID -> userID -> bool
}

func NewStats() *Stats {
    return &Stats{data: make(map[string]map[string]map[string]bool)}
}

func (s *Stats) AddView(articleID, userID string) {
    s.mu.Lock()
    defer s.mu.Unlock()
    date := time.Now().UTC().Format("2006-01-02")
    if s.data[date] == nil {
        s.data[date] = make(map[string]map[string]bool)
    }
    if s.data[date][articleID] == nil {
        s.data[date][articleID] = make(map[string]bool)
    }
    s.data[date][articleID][userID] = true
}

func (s *Stats) GetUniqueViews(articleID, date string) int {
    s.mu.RLock()
    defer s.mu.RUnlock()
    if s.data[date] == nil || s.data[date][articleID] == nil {
        return 0
    }
    return len(s.data[date][articleID])
}

This approach allows real-time accumulation of unique views and retrieval of statistics for any day. If necessary, periodic cleanup of old data can be added to prevent memory buildup.