forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCacheLock.cs
114 lines (104 loc) · 2.38 KB
/
CacheLock.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections;
namespace NHibernate.Cache
{
/// <summary>
/// A soft lock which supports concurrent locking,
/// timestamped with the time it was released
/// </summary>
/// <remarks>
/// This class was named Lock in H2.1
/// </remarks>
[Serializable]
public class CacheLock : ReadWriteCache.ILockable, ISoftLock
{
private long unlockTimestamp = -1;
private int multiplicity = 1;
private bool concurrentLock = false;
private long timeout;
private readonly int id;
private readonly object version;
public CacheLock(long timeout, int id, object version)
{
this.timeout = timeout;
this.id = id;
this.version = version;
}
/// <summary>
/// Increment the lock, setting the
/// new lock timeout
/// </summary>
public CacheLock Lock(long timeout, int id)
{
concurrentLock = true;
multiplicity++;
this.timeout = timeout;
return this;
}
/// <summary>
/// Decrement the lock, setting the unlock
/// timestamp if now unlocked
/// </summary>
/// <param name="currentTimestamp"></param>
public void Unlock(long currentTimestamp)
{
if (--multiplicity == 0)
{
unlockTimestamp = currentTimestamp;
}
}
/// <summary>
/// Can the timestamped transaction re-cache this
/// locked item now?
/// </summary>
public bool IsPuttable(long txTimestamp, object newVersion, IComparer comparator)
{
if (timeout < txTimestamp)
{
return true;
}
if (multiplicity > 0)
{
return false;
}
return version == null ?
unlockTimestamp < txTimestamp :
comparator.Compare(version, newVersion) < 0;
//by requiring <, we rely on lock timeout in the case of an unsuccessful update!
}
/// <summary>
/// Was this lock held concurrently by multiple
/// transactions?
/// </summary>
public bool WasLockedConcurrently
{
get { return concurrentLock; }
}
/// <summary>
/// Yes, this is a lock
/// </summary>
public bool IsLock
{
get { return true; }
}
/// <summary>
/// locks are not returned to the client!
/// </summary>
public bool IsGettable(long txTimestamp)
{
return false;
}
public int Id
{
get { return id; }
}
public override string ToString()
{
return "CacheLock{id=" + id +
",version=" + version +
",multiplicity=" + multiplicity +
",unlockTimestamp=" + unlockTimestamp +
"}";
}
}
}