Skip to content

Commit

Permalink
Merge pull request #15 from MattEstHaut/feature/cleaning
Browse files Browse the repository at this point in the history
Améliore le nettoyage de la base de données
  • Loading branch information
MattEstHaut authored Jun 3, 2024
2 parents 770f76a + c72c7cc commit 0016504
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 26 deletions.
77 changes: 55 additions & 22 deletions src/Server/Database.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,87 @@
using System.Collections.Concurrent;

public class Database
public class Database : IDisposable
{
private ConcurrentDictionary<string, string> _data = new();
private ConcurrentDictionary<string, DateTimeOffset> _ex = new();
private readonly ConcurrentDictionary<string, string> _data = new();
private readonly ConcurrentDictionary<string, DateTimeOffset> _ex = new();
private readonly object _lock = new();
private readonly object _cleanLock = new();
private CancellationTokenSource _cts = new();

public Database(long cleanupInterval = 1000)
public Database()
{
System.Timers.Timer timer = new(cleanupInterval);
timer.Elapsed += (sender, e) => Clean();
timer.AutoReset = true;
timer.Start();
_ = Task.Run(Clean);
}

public void Set(string key, string value)
{
_data[key] = value;
_ex.Remove(key, out _);
lock (_lock)
{
_data[key] = value;
_ex.Remove(key, out _);
}
}

public void Set(string key, string value, long ex)
{
_data[key] = value;
_ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex);
lock (_lock)
{
_data[key] = value;
_ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex);
}
}

public void Set(string key, long ex)
{
if (_data.ContainsKey(key))
_ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex);
lock (_lock)
{
if (_data.ContainsKey(key))
_ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex);
}
}

public void Del(string key)
{
_data.Remove(key, out _);
_ex.Remove(key, out _);
lock (_lock)
{
_data.Remove(key, out _);
_ex.Remove(key, out _);
}
}

public string? Get(string key)
{
if (_ex.TryGetValue(key, out var expire) && expire < DateTimeOffset.UtcNow)
Del(key);
lock (_lock)
{
if (_ex.TryGetValue(key, out var expire) && expire < DateTimeOffset.UtcNow)
Del(key);

return _data.TryGetValue(key, out var value) ? value : null;
return _data.TryGetValue(key, out var value) ? value : null;
}
}

public void Lock() => Monitor.Enter(_cleanLock);

public void Unlock() => Monitor.Exit(_cleanLock);

private void Clean()
{
foreach (var (key, expire) in _ex)
if (expire < DateTimeOffset.UtcNow)
Del(key);
while (!_cts.Token.IsCancellationRequested)
{
foreach (var (key, expire) in _ex)
{
if (expire < DateTimeOffset.UtcNow)
lock (_cleanLock) Del(key);
}
}
}

public void Dispose()
{
_cts.Cancel();
_cts.Dispose();
_data.Clear();
_ex.Clear();
GC.SuppressFinalize(this);
}
}
2 changes: 1 addition & 1 deletion src/Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

if (args.Length > 0) port = int.Parse(args[0]);

var database = new Database(15000);
var database = new Database();
var server = new Server(port, database);
server.Run();
6 changes: 3 additions & 3 deletions tests/Server.UnitTests/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class DatabaseTests
[InlineData("", "")]
public void SetGet(string key, string value)
{
var db = new Database();
using var db = new Database();
db.Set(key, value);
var result = db.Get(key);
Assert.Equal(value, result);
Expand All @@ -23,7 +23,7 @@ public void SetGet(string key, string value)
[InlineData("key2", "value", 10)]
public void SetGetEx(string key, string value, long ex)
{
var db = new Database();
using var db = new Database();
db.Set(key, value, ex);
var result = db.Get(key);
Assert.Equal(value, result);
Expand All @@ -37,7 +37,7 @@ public void SetGetEx(string key, string value, long ex)
[Fact]
public void AutoClean()
{
var db = new Database(10);
using var db = new Database();
db.Set("key1", "value");
db.Set("key2", "value", 50);
db.Set("key3", "value", 20);
Expand Down

0 comments on commit 0016504

Please sign in to comment.