Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
RuntimeCounters.cs
1using System;
3using System.Threading.Tasks;
8
10{
14 public static class RuntimeCounters
15 {
16 private static readonly Cache<CaseInsensitiveString, CounterRec> counters;
17 private static readonly object synchObject = new object();
18
19 private class CounterRec
20 {
21 public TaskCompletionSource<bool> Stored = new TaskCompletionSource<bool>();
22 public RuntimeCounter Counter;
23 public bool Changed;
24 }
25
26 static RuntimeCounters()
27 {
28 counters = new Cache<CaseInsensitiveString, CounterRec>(int.MaxValue, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(1));
29
30 counters.Removed += Counters_Removed;
31 }
32
33 private static async Task Counters_Removed(object Sender, CacheItemEventArgs<CaseInsensitiveString, CounterRec> e)
34 {
35 try
36 {
37 lock (synchObject)
38 {
39 if (!e.Value.Changed)
40 {
41 e.Value.Stored.TrySetResult(true);
42 return;
43 }
44 }
45
46 if (e.Value.Counter.Counter == 0)
47 {
48 if (!string.IsNullOrEmpty(e.Value.Counter.ObjectId))
49 await Database.Delete(e.Value.Counter);
50 }
51 else
52 {
53 if (string.IsNullOrEmpty(e.Value.Counter.ObjectId))
54 await Database.Insert(e.Value.Counter);
55 else
56 await Database.Update(e.Value.Counter);
57 }
58
59 e.Value.Stored.TrySetResult(true);
60 }
61 catch (Exception)
62 {
63 e.Value.Stored.TrySetResult(false);
64 }
65 }
66
71 public static async Task<int> FlushAsync()
72 {
73 CounterRec[] Records = counters.GetValues();
74 counters.Clear();
75
76 foreach (CounterRec Rec in Records)
77 await Rec.Stored.Task;
78
79 return Records.Length;
80 }
81
87 public static Task<long> IncrementCounter(CaseInsensitiveString Key)
88 {
89 return IncrementCounter(Key, 1);
90 }
91
98 public static async Task<long> IncrementCounter(CaseInsensitiveString Key, long Delta)
99 {
100 lock (synchObject)
101 {
102 if (counters.TryGetValue(Key, out CounterRec Rec))
103 {
104 Rec.Counter.Counter += Delta;
105 Rec.Changed = true;
106
107 return Rec.Counter.Counter;
108 }
109 }
110
111 RuntimeCounter Counter = await Database.FindFirstDeleteRest<RuntimeCounter>(new FilterFieldEqualTo("Key", Key));
112
113 lock (synchObject)
114 {
115 if (counters.TryGetValue(Key, out CounterRec Rec))
116 {
117 Rec.Counter.Counter += Delta;
118 Rec.Changed = true;
119
120 return Rec.Counter.Counter;
121 }
122 else
123 {
124 if (Counter is null)
125 {
126 Counter = new RuntimeCounter()
127 {
128 Counter = Delta,
129 Key = Key
130 };
131
132 counters[Key] = new CounterRec()
133 {
134 Counter = Counter,
135 Changed = true
136 };
137 }
138 else
139 {
140 Counter.Counter += Delta;
141 counters[Key] = new CounterRec()
142 {
143 Counter = Counter,
144 Changed = true
145 };
146
147 return Counter.Counter;
148 }
149 }
150 }
151
152 return Counter.Counter;
153 }
154
160 public static Task<long> DecrementCounter(CaseInsensitiveString Key)
161 {
162 return IncrementCounter(Key, -1);
163 }
164
171 public static Task<long> DecrementCounter(CaseInsensitiveString Key, long Delta)
172 {
173 return IncrementCounter(Key, -Delta);
174 }
175
181 public static async Task<long> GetCount(CaseInsensitiveString Key)
182 {
183 lock (synchObject)
184 {
185 if (counters.TryGetValue(Key, out CounterRec Rec))
186 return Rec.Counter.Counter;
187 }
188
189 RuntimeCounter Counter = await Database.FindFirstDeleteRest<RuntimeCounter>(new FilterFieldEqualTo("Key", Key));
190
191 lock (synchObject)
192 {
193 if (counters.TryGetValue(Key, out CounterRec Rec))
194 return Rec.Counter.Counter;
195 else
196 {
197 if (Counter is null)
198 {
199 Counter = new RuntimeCounter()
200 {
201 Counter = 0,
202 Key = Key
203 };
204
205 counters[Key] = new CounterRec()
206 {
207 Counter = Counter,
208 Changed = false
209 };
210 }
211 else
212 {
213 counters[Key] = new CounterRec()
214 {
215 Counter = Counter,
216 Changed = false
217 };
218 }
219 }
220 }
221
222 return Counter.Counter;
223 }
224
225 #region Batch Get
226
231 public static Dictionary<string, long> GetWhere()
232 {
233 return GetWhereAsync().Result;
234 }
235
240 public static async Task<Dictionary<string, long>> GetWhereAsync()
241 {
242 IEnumerable<RuntimeCounter> Counters = await Database.Find<RuntimeCounter>();
243 return ConvertToDictionary(Counters);
244 }
245
251 public static Dictionary<string, long> GetWhere(Filter Filter)
252 {
253 return GetWhereAsync(Filter).Result;
254 }
255
261 public static async Task<Dictionary<string, long>> GetWhereAsync(Filter Filter)
262 {
263 IEnumerable<RuntimeCounter> Counters = await Database.Find<RuntimeCounter>(Filter);
264 return ConvertToDictionary(Counters);
265 }
266
267 private static Dictionary<string, long> ConvertToDictionary(IEnumerable<RuntimeCounter> Counters)
268 {
269 Dictionary<string, long> Result = new Dictionary<string, long>();
270
271 lock (synchObject)
272 {
273 foreach (RuntimeCounter Counter in Counters)
274 {
275 if (counters.TryGetValue(Counter.Key, out CounterRec Rec))
276 Result[Counter.Key] = Rec.Counter.Counter;
277 else
278 Result[Counter.Key] = Counter.Counter;
279 }
280 }
281
282 return Result;
283 }
284
290 public static Dictionary<string, long> GetWhereKeyLikeRegEx(string KeyPattern)
291 {
292 return GetWhere(new FilterFieldLikeRegEx("Key", KeyPattern));
293 }
294
300 public static Task<Dictionary<string, long>> GetWhereKeyLikeRegExAsync(string KeyPattern)
301 {
302 return GetWhereAsync(new FilterFieldLikeRegEx("Key", KeyPattern));
303 }
304
311 public static Dictionary<string, long> GetWhereKeyLike(string Key, string Wildcard)
312 {
313 return GetWhere(new FilterFieldLikeRegEx("Key", Database.WildcardToRegex(Key, Wildcard)));
314 }
315
322 public static Task<Dictionary<string, long>> GetWhereKeyLikeAsync(string Key, string Wildcard)
323 {
324 return GetWhereAsync(new FilterFieldLikeRegEx("Key", Database.WildcardToRegex(Key, Wildcard)));
325 }
326
327 #endregion
328
329 }
330}
Represents a case-insensitive string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static string WildcardToRegex(string s, string Wildcard)
Converts a wildcard string to a regular expression string.
Definition: Database.cs:2426
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:1211
static async Task Delete(object Object)
Deletes an object in the database.
Definition: Database.cs:1291
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:238
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:97
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field matching a given regular expression.
Base class for all filter classes.
Definition: Filter.cs:15
Implements an in-memory cache.
Definition: Cache.cs:17
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.
Static class managing persistent counters.
static Task< long > DecrementCounter(CaseInsensitiveString Key, long Delta)
Decrements a counter.
static async Task< int > FlushAsync()
Flushes all cached counters to the database.
static Dictionary< string, long > GetWhere(Filter Filter)
Gets available counters, matching a search filter.
static Dictionary< string, long > GetWhere()
Gets available counters.
static Task< Dictionary< string, long > > GetWhereKeyLikeAsync(string Key, string Wildcard)
Gets available counters, matching a search filter.
static async Task< Dictionary< string, long > > GetWhereAsync()
Gets available counters.
static Task< long > IncrementCounter(CaseInsensitiveString Key)
Increments a counter.
static async Task< long > IncrementCounter(CaseInsensitiveString Key, long Delta)
Increments a counter.
static Task< long > DecrementCounter(CaseInsensitiveString Key)
Decrements a counter.
static async Task< long > GetCount(CaseInsensitiveString Key)
Gets the current count of a counter.
static Dictionary< string, long > GetWhereKeyLike(string Key, string Wildcard)
Gets available counters, matching a search filter.
static async Task< Dictionary< string, long > > GetWhereAsync(Filter Filter)
Gets available counters, matching a search filter.
static Dictionary< string, long > GetWhereKeyLikeRegEx(string KeyPattern)
Gets available counters, matching a search filter.
static Task< Dictionary< string, long > > GetWhereKeyLikeRegExAsync(string KeyPattern)
Gets available counters, matching a search filter.