Skip to content

Commit 37bc655

Browse files
author
Doug Schmidt
authored
Merge pull request #277 from DougSchmidt-AI/feature/PF-1205-PointZillaNotes
PF-1205 - Added proper note-combining logic
2 parents 8f1f857 + a70e479 commit 37bc655

File tree

3 files changed

+108
-45
lines changed

3 files changed

+108
-45
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using NodaTime;
2+
3+
namespace PointZilla
4+
{
5+
public static class IntervalExtensions
6+
{
7+
public static bool Intersects(this Interval interval1, Interval interval2)
8+
{
9+
return !interval1.Disjoint(interval2);
10+
}
11+
12+
public static bool Intersects(this Interval? interval1, Interval? interval2)
13+
{
14+
return interval1.HasValue && interval2.HasValue && interval1.Value.Intersects(interval2.Value);
15+
}
16+
17+
private static bool Disjoint(this Interval interval1, Interval interval2)
18+
{
19+
return interval1.IsEmpty() ||
20+
interval2.IsEmpty() ||
21+
interval1.End <= interval2.Start ||
22+
interval2.End <= interval1.Start;
23+
}
24+
25+
public static bool IsEmpty(this Interval interval)
26+
{
27+
return interval.Start.Equals(interval.End);
28+
}
29+
}
30+
}

TimeSeries/PublicApis/SdkExamples/PointZilla/PointZilla.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
<Compile Include="CommandType.cs" />
162162
<Compile Include="Context.cs" />
163163
<Compile Include="CreateMode.cs" />
164+
<Compile Include="IntervalExtensions.cs" />
164165
<Compile Include="PointReaders\CsvNotesReader.cs" />
165166
<Compile Include="PointReaders\CsvReader.cs" />
166167
<Compile Include="CsvWriter.cs" />

TimeSeries/PublicApis/SdkExamples/PointZilla/PointsAppender.cs

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ public void AppendPoints()
3333

3434
(Points, Notes) = GetPoints();
3535

36-
if (Context.IgnoreNotes)
37-
Notes.Clear();
36+
AdjustNotes();
3837

3938
if (Points.All(p => p.Type != PointType.Gap))
4039
{
@@ -140,6 +139,81 @@ public void AppendPoints()
140139
}
141140
}
142141

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+
143217
private IAquariusClient CreateConnectedClient()
144218
{
145219
return string.IsNullOrWhiteSpace(Context.SessionToken)
@@ -184,57 +258,15 @@ private int AppendNotes(IAquariusClient client, TimeSeries timeSeries)
184258
if (client.ServerVersion.IsLessThan(MinimumNotesVersion))
185259
throw new ExpectedException($"You can't append time-series notes before AQTS v{MinimumNotesVersion}");
186260

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-
201261
return client.Acquisition.Post(new PostTimeSeriesMetadata
202262
{
203263
UniqueId = timeSeries.UniqueId,
204-
Notes = notes
264+
Notes = Notes
205265
}).NotesCreated;
206266
}
207267

208268
private static readonly AquariusServerVersion MinimumNotesVersion = AquariusServerVersion.Create("19.2.185");
209269

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-
238270
private TimeSeriesAppendStatus AppendPointBatch(IAquariusClient client, TimeSeries timeSeries, List<TimeSeriesPoint> points, Interval timeRange, bool isReflected, bool hasTimeRange)
239271
{
240272
AppendResponse appendResponse;

0 commit comments

Comments
 (0)