359. Logger Rate Limiter

Design a logger system that receives a stream of messages along with their timestamps. Each unique message should only be printed at most every 10 seconds (i.e. a message printed at timestamp t will prevent other identical messages from being printed until timestamp t + 10).

All messages will come in chronological order. Several messages may arrive at the same timestamp.

Implement the Logger class:

  • Logger() Initializes the logger object.
  • bool shouldPrintMessage(int timestamp, string message) Returns true if the message should be printed in the given timestamp, otherwise returns false.

 

Example 1:

Input
["Logger", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage", "shouldPrintMessage"]
[[], [1, "foo"], [2, "bar"], [3, "foo"], [8, "bar"], [10, "foo"], [11, "foo"]]
Output
[null, true, true, false, false, false, true]

Explanation
Logger logger = new Logger();
logger.shouldPrintMessage(1, "foo");  // return true, next allowed timestamp for "foo" is 1 + 10 = 11
logger.shouldPrintMessage(2, "bar");  // return true, next allowed timestamp for "bar" is 2 + 10 = 12
logger.shouldPrintMessage(3, "foo");  // 3 < 11, return false
logger.shouldPrintMessage(8, "bar");  // 8 < 12, return false
logger.shouldPrintMessage(10, "foo"); // 10 < 11, return false
logger.shouldPrintMessage(11, "foo"); // 11 >= 11, return true, next allowed timestamp for "foo" is
                                      // 11 + 10 = 21

 

Constraints:

  • 0 <= timestamp <= 109
  • Every timestamp will be passed in non-decreasing order (chronological order).
  • 1 <= message.length <= 30
  • At most 104 calls will be made to shouldPrintMessage.

Rust Solution

use std::collections::HashMap;

#[derive(Default)]
struct Logger {
    messages: HashMap<String, i32>,
}

impl Logger {
    fn new() -> Self {
        Logger {
            messages: HashMap::new(),
        }
    }

    fn should_print_message(&mut self, timestamp: i32, message: String) -> bool {
        if let Some(&t) = self.messages.get(&message) {
            if timestamp < t + 10 {
                return false;
            }
        }
        self.messages.insert(message, timestamp);
        true
    }
}

#[test]
fn test() {
    let mut logger = Logger::new();
    assert_eq!(logger.should_print_message(1, "foo".to_string()), true);
    assert_eq!(logger.should_print_message(2, "bar".to_string()), true);
    assert_eq!(logger.should_print_message(3, "foo".to_string()), false);
    assert_eq!(logger.should_print_message(8, "bar".to_string()), false);
    assert_eq!(logger.should_print_message(10, "foo".to_string()), false);
    assert_eq!(logger.should_print_message(11, "foo".to_string()), true);
}

Having problems with this solution? Click here to submit an issue on github.