I have designed a Hit Counter which can conveniently be used to design a Rate Limiter Original question: https://leetcode.com/problems/design-hit-counter/
To make it thread safe, I used lock statement.
public class HitCounter {
private readonly int duration = 300;
private readonly int[] hits, times;
//https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/statements/lock
private readonly Object lockObj = new Object();
public HitCounter(int duration) {
this.duration = duration;
times = new int[duration];
hits = new int[duration];
}
public void Hit(int timestamp) {
var idx = timestamp % duration;
lock (lockObj){
if(times[idx] != timestamp){
times[idx] = timestamp;
hits[idx] = 1;
}else{
hits[idx]++;
}
}
}
public int GetHits(int timestamp) {
var res = 0;
lock (lockObj){
for(var i = 0; i < duration; ++i){
if(timestamp - times[i] < duration){
res += hits[i];
}
}
}
return res;
}
}
My questions are:
- Is it just about surrounding the part which the two arrays are accessed with locks
- Isn't it better to use ConcurrentDictionary as an index-array? To make it lock-free
Any insight is appreciated.
ConcurrentDictionary
does lock internally but it creates multiple locks so that you can access different keys concurrently (as long as they aren't sharing a lock). \$\endgroup\$