blob: 529713bd247cca4d996baccdeec10a9984e44146 (
plain)
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
|
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace DotNetOpenId {
/// <summary>
/// A dictionary of handle/Association pairs.
/// </summary>
/// <remarks>
/// Each method is locked, even if it is only one line, so that they are thread safe
/// against each other, particularly the ones that enumerate over the list, since they
/// can break if the collection is changed by another thread during enumeration.
/// </remarks>
[DebuggerDisplay("Count = {assocs.Count}")]
internal class Associations {
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
Dictionary<string, Association> assocs;
/// <summary>
/// Instantiates a mapping between association handles and <see cref="Association"/> objects.
/// </summary>
public Associations() {
this.assocs = new Dictionary<string, Association>();
}
/// <summary>
/// Stores an <see cref="Association"/> in the collection.
/// </summary>
public void Set(Association association) {
if (association == null) throw new ArgumentNullException("association");
lock (this) {
this.assocs[association.Handle] = association;
}
}
/// <summary>
/// Returns the <see cref="Association"/> with the given handle. Null if not found.
/// </summary>
public Association Get(string handle) {
lock (this) {
Association assoc;
assocs.TryGetValue(handle, out assoc);
return assoc;
}
}
/// <summary>
/// Removes the <see cref="Association"/> with the given handle.
/// </summary>
/// <returns>Whether an <see cref="Association"/> with the given handle was in the collection for removal.</returns>
public bool Remove(string handle) {
lock (this) {
return assocs.Remove(handle);
}
}
/// <summary>
/// Gets the <see cref="Association"/> issued most recently. Null if no valid associations exist.
/// </summary>
public Association Best {
get {
lock (this) {
Association best = null;
foreach (Association assoc in assocs.Values) {
if (best == null || best.Issued < assoc.Issued)
best = assoc;
}
return best;
}
}
}
/// <summary>
/// Removes all expired associations from the collection.
/// </summary>
public void ClearExpired() {
lock (this) {
var expireds = new List<Association>(assocs.Count);
foreach (Association assoc in assocs.Values)
if (assoc.IsExpired)
expireds.Add(assoc);
foreach (Association assoc in expireds)
assocs.Remove(assoc.Handle);
}
}
}
}
|