-
Notifications
You must be signed in to change notification settings - Fork 0
/
ObjectPool.cs
78 lines (69 loc) · 2.54 KB
/
ObjectPool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Collections.Generic;
namespace SimpleObjecPool
{
public abstract class ObjectPool<T>
{
private readonly object _syncLock = new object();
private readonly long _expirationTime;
private readonly Dictionary<T, long> _locked;
private readonly Dictionary<T, long> _unlocked;
protected ObjectPool() {
_expirationTime = 30000; // 30 seconds
_locked = new Dictionary<T, long>();
_unlocked = new Dictionary<T, long>();
}
protected abstract T Create();
public abstract bool Validate(T o);
public abstract void Expire(T o);
public T CheckOut() {
lock (_syncLock)
{
long now = GetSystemMillis();
T t;
if (_unlocked.Count > 0)
{
Dictionary<T, long>.KeyCollection.Enumerator e = _unlocked.Keys.GetEnumerator();
while (e.MoveNext()) {
t = e.Current;
long unlockTime;
_unlocked.TryGetValue(t, out unlockTime);
if ( unlockTime!= default(long) && (now - unlockTime > _expirationTime)) {
// object has expired
_unlocked.Remove(t);
Expire(t);
t = default(T);
} else {
if (Validate(t)) {
_unlocked.Remove(t);
_locked.Add(t, now);
return t;
} else {
// object failed validation
_unlocked.Remove(t);
Expire(t);
t = default(T);
}
}
}
}
// no objects available, create a new one
t = Create();
_locked.Add(t, now);
return t;
}
}
public void CheckIn(T t) {
lock (_syncLock){
_locked.Remove(t);
_unlocked.Add(t, GetSystemMillis());
}
}
private long GetSystemMillis()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long millis = (long)ts.TotalMilliseconds;
return millis;
}
}
}