namespace ZB.MOM.WW.OtOpcUa.OpcUaServer; /// /// Gitea #694 item 2: the opt-in ServerHistorian:EventReadHorizon — HistoryReadEvents never reads events older than /// now − horizon. Off (, the default) a read is exact down to whatever its window says, /// which on the Gateway means a reverse / end-only read walked back with forward reads proves "nothing older" with one /// read down to the Unix epoch (#691) — ~3.8 s live on Runtime.dbo.Events, and an unfiltered one can hit the /// gateway's 30 s SQL timeout. A forward read whose StartTime is far in the past costs the same on that table. The /// horizon bounds both, at a stated price: events older than it are not returned, in either direction, on any backend. /// internal static class EventHorizon { /// /// Raises the EARLIER bound of a fresh events window to the horizon's floor (now − horizon, inclusive): the /// start of a forward [start, end) window, the exclusive lower end of a reverse (end, start] one. /// /// The window start (the later bound of a reverse read). /// The window end (the exclusive earlier bound of a reverse read). /// Whether the read is newest-first (start > end). /// The horizon; non-positive = none (nothing changes). /// Now. /// false when the whole window lies before the floor — the read is empty and must not be sent. public static bool TryClamp(ref DateTime startUtc, ref DateTime endUtc, bool reverse, TimeSpan horizon, DateTime nowUtc) { if (horizon <= TimeSpan.Zero) return true; var floor = nowUtc.Ticks - DateTime.MinValue.Ticks > horizon.Ticks ? new DateTime(nowUtc.Ticks - horizon.Ticks, DateTimeKind.Utc) : new DateTime(0, DateTimeKind.Utc); if (floor.Ticks == 0) return true; if (reverse) { if (startUtc < floor) return false; // (end, start] lies wholly before the floor var below = floor.AddTicks(-1); // exclusive lower end ⇒ the floor instant itself is read if (endUtc < below) endUtc = below; return true; } if (endUtc <= floor) return false; // [start, end) lies wholly before the floor if (startUtc < floor) startUtc = floor; return true; } }