Skip to content

Commit d223cda

Browse files
authored
TARDA-2840 Refactor DBMDataRef for thread-safe annotation access and memory-efficient size limiting (#327)
* Thread-safe access to _annotations in DBMDataRef using lock Signed-off-by: Johan Fitié <jfitie@gmail.com> * Limit _annotations dictionary size to 10,000 by removing entries when exceeded Signed-off-by: Johan Fitié <jfitie@gmail.com> * Refactor to use constant for maximum annotations size Signed-off-by: Johan Fitié <jfitie@gmail.com> * Refactor _annotations to use SortedDictionary for FIFO eviction instead of random removal Signed-off-by: Johan Fitié <jfitie@gmail.com> * Limit line length correctly Signed-off-by: Johan Fitié <jfitie@gmail.com> * Update copyright year, change maximum number of annotations Signed-off-by: Johan Fitié <jfitie@gmail.com> --------- Signed-off-by: Johan Fitié <jfitie@gmail.com>
1 parent ce92268 commit d223cda

3 files changed

Lines changed: 45 additions & 21 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# DBM
44
Dynamic Bandwidth Monitor\
55
Leak detection method implemented in a real-time data historian\
6-
Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V.
6+
Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V.
77

88
## Description
99
Water company Vitens has created a demonstration site called the Vitens Innovation Playground (VIP), in which new technologies and methodologies are developed, tested, and demonstrated. The projects conducted in the demonstration site can be categorized into one of four themes: energy optimization, real-time leak detection, online water quality monitoring, and customer interaction. In the real-time leak detection theme, a method for leak detection based on statistical demand forecasting was developed.

src/DBMDataRef/DBMDataRef.vb

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
' Dynamic Bandwidth Monitor
22
' Leak detection method implemented in a real-time data historian
3-
' Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V.
3+
' Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V.
44
'
55
' This file is part of DBM.
66
'
@@ -25,6 +25,7 @@ Imports System.DateTime
2525
Imports System.Double
2626
Imports System.Math
2727
Imports System.Runtime.InteropServices
28+
Imports System.Threading
2829
Imports OSIsoft.AF.Asset
2930
Imports OSIsoft.AF.Asset.AFAttributeTrait
3031
Imports OSIsoft.AF.Data
@@ -83,13 +84,15 @@ Namespace Vitens.DynamicBandwidthMonitor
8384
' process output.
8485

8586

87+
Const MaxAnnotationsSize As Integer = 1000 ' Maximum number of annotations
8688
Const StaleDataMinutes As Integer = 10 ' Minutes until snapshot is stale
8789
Const CategoryNoCorrelation As String = "NoCorrelation"
8890
Const pValueLoHi As Double = 0.95 ' Confidence interval for Lo and Hi
8991
Const pValueMinMax As Double = 0.9999 ' CI for Minimum and Maximum
9092

9193

92-
Private _annotations As New Dictionary(Of AFTime, Object)
94+
Private _lock As New Object ' Object for exclusive lock on critical section.
95+
Private _annotations As New SortedDictionary(Of AFTime, Object)
9396
Private Shared _dbm As New DBM(New DBMLoggerAFTrace)
9497

9598

@@ -279,20 +282,31 @@ Namespace Vitens.DynamicBandwidthMonitor
279282

280283
If value IsNot Nothing Then ' Key
281284

282-
_annotations.Remove(value.Timestamp) ' Remove existing
283-
value.Annotated = False
285+
Monitor.Enter(_lock) ' Block
286+
Try
284287

285-
If annotation IsNot Nothing Then ' Value
288+
_annotations.Remove(value.Timestamp) ' Remove existing
289+
value.Annotated = False
286290

287-
DBM.Logger.LogDebug(
288-
"value.Timestamp " &
289-
value.Timestamp.LocalTime.ToString("s") & "; " &
290-
"annotation " & DirectCast(annotation, String), Attribute.GetPath)
291+
If annotation IsNot Nothing Then ' Value
291292

292-
_annotations.Add(value.Timestamp, annotation) ' Add
293-
value.Annotated = True
293+
While _annotations.Count >= MaxAnnotationsSize ' Limit size
294+
_annotations.Remove(_annotations.Keys.First()) ' Remove oldest
295+
End While
294296

295-
End If
297+
DBM.Logger.LogDebug(
298+
"value.Timestamp " &
299+
value.Timestamp.LocalTime.ToString("s") & "; " &
300+
"annotation " & DirectCast(annotation, String), Attribute.GetPath)
301+
302+
_annotations.Add(value.Timestamp, annotation) ' Add
303+
value.Annotated = True
304+
305+
End If
306+
307+
Finally
308+
Monitor.Exit(_lock) ' Unblock
309+
End Try
296310

297311
End If
298312

@@ -308,12 +322,22 @@ Namespace Vitens.DynamicBandwidthMonitor
308322
' attributes"
309323

310324
GetAnnotation = Nothing
311-
If value IsNot Nothing AndAlso
312-
_annotations.TryGetValue(value.Timestamp, GetAnnotation) Then
313-
_annotations.Remove(value.Timestamp) ' Remove after get
314-
Return GetAnnotation
315-
Else
316-
Return String.Empty ' Default
325+
If value IsNot Nothing Then ' Key
326+
327+
Monitor.Enter(_lock) ' Block
328+
Try
329+
330+
If _annotations.TryGetValue(value.Timestamp, GetAnnotation) Then
331+
_annotations.Remove(value.Timestamp) ' Remove after get
332+
Return GetAnnotation
333+
Else
334+
Return String.Empty ' Default
335+
End If
336+
337+
Finally
338+
Monitor.Exit(_lock) ' Unblock
339+
End Try
340+
317341
End If
318342

319343
End Function

src/dbm/DBMManifest.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
' Dynamic Bandwidth Monitor
22
' Leak detection method implemented in a real-time data historian
3-
' Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V.
3+
' Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V.
44
'
55
' This file is part of DBM.
66
'
@@ -30,6 +30,6 @@
3030
"Leak detection method implemented in a real-time data historian")>
3131

3232
<assembly:System.Reflection.AssemblyCopyright(
33-
"Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V.")>
33+
"Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V.")>
3434

3535
<assembly:System.Reflection.AssemblyCompany("Vitens N.V.")>

0 commit comments

Comments
 (0)