@@ -33,8 +33,7 @@ public void AppendPoints()
33
33
34
34
( Points , Notes ) = GetPoints ( ) ;
35
35
36
- if ( Context . IgnoreNotes )
37
- Notes . Clear ( ) ;
36
+ AdjustNotes ( ) ;
38
37
39
38
if ( Points . All ( p => p . Type != PointType . Gap ) )
40
39
{
@@ -140,6 +139,81 @@ public void AppendPoints()
140
139
}
141
140
}
142
141
142
+ private void AdjustNotes ( )
143
+ {
144
+ if ( Context . IgnoreNotes )
145
+ {
146
+ Notes . Clear ( ) ;
147
+ return ;
148
+ }
149
+
150
+ var noteCombiner = new NoteCombiner ( ) ;
151
+
152
+ foreach ( var note in Notes
153
+ . Select ( AdjustNoteTextAndTimeRange )
154
+ . OrderBy ( note => note . TimeRange ? . Start )
155
+ . ThenByDescending ( note => note . TimeRange ? . End ) )
156
+ {
157
+ noteCombiner . AddOverlappingIntervalMetadata ( note , ( note1 , note2 ) => note1 . NoteText != note2 . NoteText ) ;
158
+ }
159
+
160
+ Notes = noteCombiner . Items ;
161
+ }
162
+
163
+ private TimeSeriesNote AdjustNoteTextAndTimeRange ( TimeSeriesNote note )
164
+ {
165
+ if ( note . TimeRange . HasValue && note . TimeRange . Value . End == note . TimeRange . Value . Start )
166
+ {
167
+ note . TimeRange = new Interval ( note . TimeRange . Value . Start , note . TimeRange . Value . End . PlusTicks ( 1 ) ) ;
168
+ }
169
+
170
+ const int maxNoteLength = 500 ;
171
+
172
+ if ( note . NoteText . Length > maxNoteLength )
173
+ {
174
+ note . NoteText = note . NoteText . Substring ( 0 , maxNoteLength - 20 ) + " ... note truncated." ;
175
+ }
176
+
177
+ return note ;
178
+ }
179
+
180
+ private class NoteCombiner
181
+ {
182
+ public List < TimeSeriesNote > Items { get ; } = new List < TimeSeriesNote > ( ) ;
183
+
184
+ private TimeSeriesNote CurrentItem { get ; set ; }
185
+
186
+ public void AddOverlappingIntervalMetadata (
187
+ TimeSeriesNote newItem ,
188
+ Func < TimeSeriesNote , TimeSeriesNote , bool > isDifferent )
189
+ {
190
+ var overlappingItem = Items
191
+ . LastOrDefault ( item => item . TimeRange . Intersects ( newItem . TimeRange ) && ! isDifferent ( item , newItem ) ) ;
192
+
193
+ if ( overlappingItem == null )
194
+ {
195
+ CurrentItem = newItem ;
196
+ Items . Add ( CurrentItem ) ;
197
+
198
+ return ;
199
+ }
200
+
201
+ CurrentItem = overlappingItem ;
202
+
203
+ ExtendCurrentItem ( newItem . TimeRange ) ;
204
+ }
205
+
206
+ private void ExtendCurrentItem ( Interval ? timeRange )
207
+ {
208
+ if ( ! timeRange . HasValue || ! CurrentItem . TimeRange . HasValue )
209
+ return ;
210
+
211
+ CurrentItem . TimeRange = new Interval (
212
+ Instant . Min ( CurrentItem . TimeRange . Value . Start , timeRange . Value . Start ) ,
213
+ Instant . Max ( CurrentItem . TimeRange . Value . End , timeRange . Value . End ) ) ;
214
+ }
215
+ }
216
+
143
217
private IAquariusClient CreateConnectedClient ( )
144
218
{
145
219
return string . IsNullOrWhiteSpace ( Context . SessionToken )
@@ -184,57 +258,15 @@ private int AppendNotes(IAquariusClient client, TimeSeries timeSeries)
184
258
if ( client . ServerVersion . IsLessThan ( MinimumNotesVersion ) )
185
259
throw new ExpectedException ( $ "You can't append time-series notes before AQTS v{ MinimumNotesVersion } ") ;
186
260
187
- var notes = CoalesceAdjacentNotes ( Notes )
188
- . Select ( note =>
189
- {
190
- const int maxNoteLength = 500 ;
191
-
192
- if ( note . NoteText . Length > maxNoteLength )
193
- {
194
- note . NoteText = note . NoteText . Substring ( 0 , maxNoteLength - 20 ) + " ... note truncated." ;
195
- }
196
-
197
- return note ;
198
- } )
199
- . ToList ( ) ;
200
-
201
261
return client . Acquisition . Post ( new PostTimeSeriesMetadata
202
262
{
203
263
UniqueId = timeSeries . UniqueId ,
204
- Notes = notes
264
+ Notes = Notes
205
265
} ) . NotesCreated ;
206
266
}
207
267
208
268
private static readonly AquariusServerVersion MinimumNotesVersion = AquariusServerVersion . Create ( "19.2.185" ) ;
209
269
210
- private IEnumerable < TimeSeriesNote > CoalesceAdjacentNotes ( IEnumerable < TimeSeriesNote > notes )
211
- {
212
- TimeSeriesNote previousNote = null ;
213
-
214
- foreach ( var note in notes
215
- . OrderBy ( note => note . TimeRange ? . Start )
216
- . ThenBy ( note => note . TimeRange ? . End ) )
217
- {
218
- if ( previousNote != null )
219
- {
220
- if ( previousNote . TimeRange ? . End == note . TimeRange ? . Start && previousNote . NoteText == note . NoteText )
221
- {
222
- previousNote . TimeRange = new Interval (
223
- previousNote . TimeRange ? . Start ?? throw new ExpectedException ( "Invalid TimeRange Start value" ) ,
224
- note . TimeRange ? . End ?? throw new ExpectedException ( "Invalid TimeRange End value" ) ) ;
225
- continue ;
226
- }
227
-
228
- yield return previousNote ;
229
- }
230
-
231
- previousNote = note ;
232
- }
233
-
234
- if ( previousNote != null )
235
- yield return previousNote ;
236
- }
237
-
238
270
private TimeSeriesAppendStatus AppendPointBatch ( IAquariusClient client , TimeSeries timeSeries , List < TimeSeriesPoint > points , Interval timeRange , bool isReflected , bool hasTimeRange )
239
271
{
240
272
AppendResponse appendResponse ;
0 commit comments