public override void Update(EventBean[] newData, EventBean[] oldData) { using (Instrument.With( i => i.QViewProcessIRStream(this, _viewFactory.ViewName, newData, oldData), i => i.AViewProcessIRStream())) { EventBean[] postOldEventsArray = null; // Remove old data if (oldData != null) { for (int i = 0; i < oldData.Length; i++) { var oldDataItem = oldData[i]; var sortValues = GetTimestamp(oldDataItem); var result = CollectionUtil.RemoveEventByKeyLazyListMap(sortValues, oldDataItem, _sortedEvents); if (result) { _eventCount--; if (postOldEventsArray == null) { postOldEventsArray = oldData; } else { postOldEventsArray = CollectionUtil.AddArrayWithSetSemantics( postOldEventsArray, oldData); } InternalHandleRemoved(sortValues, oldDataItem); } } } if ((newData != null) && (newData.Length > 0)) { // figure out the current tail time long engineTime = _agentInstanceContext.StatementContext.SchedulingService.Time; long windowTailTime = engineTime - _timeDeltaComputation.DeltaAdd(engineTime) + 1; long oldestEvent = long.MaxValue; if (_sortedEvents.IsNotEmpty()) { oldestEvent = (long)_sortedEvents.Keys.First(); } bool addedOlderEvent = false; // add events or post events as remove stream if already older then tail time List <EventBean> postOldEvents = null; for (int i = 0; i < newData.Length; i++) { // get timestamp of event var newEvent = newData[i]; var timestamp = GetTimestamp(newEvent); // if the event timestamp indicates its older then the tail of the window, release it if (timestamp < windowTailTime) { if (postOldEvents == null) { postOldEvents = new List <EventBean>(2); } postOldEvents.Add(newEvent); } else { if (timestamp < oldestEvent) { addedOlderEvent = true; oldestEvent = timestamp.Value; } // add to list CollectionUtil.AddEventByKeyLazyListMapBack(timestamp, newEvent, _sortedEvents); _eventCount++; InternalHandleAdd(timestamp, newEvent); } } // If we do have data, check the callback if (_sortedEvents.IsNotEmpty()) { // If we haven't scheduled a callback yet, schedule it now if (!_isCallbackScheduled) { long callbackWait = oldestEvent - windowTailTime + 1; _agentInstanceContext.StatementContext.SchedulingService.Add( callbackWait, _handle, _scheduleSlot); _isCallbackScheduled = true; } else { // We may need to reschedule, and older event may have been added if (addedOlderEvent) { oldestEvent = (long)_sortedEvents.Keys.First(); long callbackWait = oldestEvent - windowTailTime + 1; _agentInstanceContext.StatementContext.SchedulingService.Remove(_handle, _scheduleSlot); _agentInstanceContext.StatementContext.SchedulingService.Add( callbackWait, _handle, _scheduleSlot); _isCallbackScheduled = true; } } } if (postOldEvents != null) { postOldEventsArray = postOldEvents.ToArray(); } if (_optionalSortedRandomAccess != null) { _optionalSortedRandomAccess.Refresh(_sortedEvents, _eventCount, _eventCount); } } // Update child views if (HasViews) { Instrument.With( i => i.QViewIndicate(this, _viewFactory.ViewName, newData, postOldEventsArray), i => i.AViewIndicate(), () => UpdateChildren(newData, postOldEventsArray)); } } }
public void TestGet() { _access.Refresh(_sortedEvents, 0, 10); Assert.IsNull(_access.GetNewData(0)); Assert.IsNull(_access.GetNewData(1)); Add("C", _events[0]); _access.Refresh(_sortedEvents, 1, 10); AssertData(new EventBean[] { _events[0] } ); Add("E", _events[1]); _access.Refresh(_sortedEvents, 2, 10); AssertData(new EventBean[] { _events[0], _events[1] } ); Add("A", _events[2]); _access.Refresh(_sortedEvents, 3, 10); AssertData(new EventBean[] { _events[2], _events[0], _events[1] } ); Add("C", _events[4]); _access.Refresh(_sortedEvents, 4, 10); AssertData(new EventBean[] { _events[2], _events[4], _events[0], _events[1] } ); Add("E", _events[5]); _access.Refresh(_sortedEvents, 5, 10); AssertData(new EventBean[] { _events[2], _events[4], _events[0], _events[5], _events[1] } ); Add("A", _events[6]); _access.Refresh(_sortedEvents, 6, 10); AssertData(new EventBean[] { _events[6], _events[2], _events[4], _events[0], _events[5], _events[1] } ); Add("B", _events[7]); _access.Refresh(_sortedEvents, 7, 10); AssertData( new EventBean[] { _events[6], _events[2], _events[7], _events[4], _events[0], _events[5], _events[1] } ); Add("F", _events[8]); _access.Refresh(_sortedEvents, 8, 10); AssertData( new EventBean[] { _events[6], _events[2], _events[7], _events[4], _events[0], _events[5], _events[1], _events[8] } ); // A A B C C E E F Add("D", _events[9]); _access.Refresh(_sortedEvents, 9, 10); Assert.AreSame(_events[9], _access.GetNewData(5)); }
public override void Update(EventBean[] newData, EventBean[] oldData) { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().QViewProcessIRStream(this, _sortWindowViewFactory.ViewName, newData, oldData); } OneEventCollection removedEvents = null; // Remove old data if (oldData != null) { for (var i = 0; i < oldData.Length; i++) { var oldDataItem = oldData[i]; var sortValues = GetSortValues(oldDataItem); var result = CollectionUtil.RemoveEventByKeyLazyListMap(sortValues, oldDataItem, _sortedEvents); if (result) { _eventCount--; if (removedEvents == null) { removedEvents = new OneEventCollection(); } removedEvents.Add(oldDataItem); InternalHandleRemoved(sortValues, oldDataItem); } } } // Add new data if (newData != null) { for (var i = 0; i < newData.Length; i++) { var newDataItem = newData[i]; var sortValues = GetSortValues(newDataItem); CollectionUtil.AddEventByKeyLazyListMapFront(sortValues, newDataItem, _sortedEvents); _eventCount++; InternalHandleAdd(sortValues, newDataItem); } } // Remove data that sorts to the bottom of the window if (_eventCount > _sortWindowSize) { var removeCount = _eventCount - _sortWindowSize; for (var i = 0; i < removeCount; i++) { // Remove the last element of the last key - sort order is key and then natural order of arrival var lastKey = _sortedEvents.Keys.Last(); var lastEntry = _sortedEvents.Get(lastKey); if (lastEntry is IList <EventBean> ) { var events = (IList <EventBean>)lastEntry; var theEvent = events.DeleteAt(events.Count - 1); // remove oldest event, newest events are first in list _eventCount--; if (events.IsEmpty()) { _sortedEvents.Remove(lastKey); } if (removedEvents == null) { removedEvents = new OneEventCollection(); } removedEvents.Add(theEvent); InternalHandleRemoved(lastKey, theEvent); } else { var theEvent = (EventBean)lastEntry; _eventCount--; _sortedEvents.Remove(lastKey); if (removedEvents == null) { removedEvents = new OneEventCollection(); } removedEvents.Add(theEvent); InternalHandleRemoved(lastKey, theEvent); } } } // If there are child views, fireStatementStopped Update method if (_optionalSortedRandomAccess != null) { _optionalSortedRandomAccess.Refresh(_sortedEvents, _eventCount, _sortWindowSize); } if (HasViews) { EventBean[] expiredArr = null; if (removedEvents != null) { expiredArr = removedEvents.ToArray(); } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().QViewIndicate(this, _sortWindowViewFactory.ViewName, newData, expiredArr); } UpdateChildren(newData, expiredArr); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().AViewIndicate(); } } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().AViewProcessIRStream(); } }
public override void Update(EventBean[] newData, EventBean[] oldData) { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().QViewProcessIRStream(this, _rankWindowViewFactory.ViewName, newData, oldData); } var removedEvents = new OneEventCollection(); // Remove old data if (oldData != null) { for (var i = 0; i < oldData.Length; i++) { var uniqueKey = GetUniqueValues(oldData[i]); var existingSortKey = _uniqueKeySortKeys.Get(uniqueKey); if (existingSortKey == null) { continue; } var theEvent = RemoveFromSortedEvents(existingSortKey, uniqueKey); if (theEvent != null) { _numberOfEvents--; _uniqueKeySortKeys.Remove(uniqueKey); removedEvents.Add(theEvent); InternalHandleRemovedKey(existingSortKey, oldData[i]); } } } // Add new data if (newData != null) { for (var i = 0; i < newData.Length; i++) { var uniqueKey = GetUniqueValues(newData[i]); var newSortKey = GetSortValues(newData[i]); var existingSortKey = _uniqueKeySortKeys.Get(uniqueKey); // not currently found: its a new entry if (existingSortKey == null) { CompareAndAddOrPassthru(newData[i], uniqueKey, newSortKey, removedEvents); } // same unique-key event found already, remove and add again else { // key did not change, perform in-place substitute of event if (existingSortKey.Equals(newSortKey)) { var replaced = InplaceReplaceSortedEvents(existingSortKey, uniqueKey, newData[i]); if (replaced != null) { removedEvents.Add(replaced); } InternalHandleReplacedKey(newSortKey, newData[i], replaced); } else { var removed = RemoveFromSortedEvents(existingSortKey, uniqueKey); if (removed != null) { _numberOfEvents--; removedEvents.Add(removed); InternalHandleRemovedKey(existingSortKey, removed); } CompareAndAddOrPassthru(newData[i], uniqueKey, newSortKey, removedEvents); } } } } // Remove data that sorts to the bottom of the window if (_numberOfEvents > _sortWindowSize) { while (_numberOfEvents > _sortWindowSize) { var lastKey = _sortedEvents.Keys.Last(); var existing = _sortedEvents.Get(lastKey); if (existing is IList <EventBean> ) { var existingList = (IList <EventBean>)existing; while (_numberOfEvents > _sortWindowSize && !existingList.IsEmpty()) { var newestEvent = existingList.DeleteAt(0); var uniqueKey = GetUniqueValues(newestEvent); _uniqueKeySortKeys.Remove(uniqueKey); _numberOfEvents--; removedEvents.Add(newestEvent); InternalHandleRemovedKey(existing, newestEvent); } if (existingList.IsEmpty()) { _sortedEvents.Remove(lastKey); } } else { var lastSortedEvent = (EventBean)existing; var uniqueKey = GetUniqueValues(lastSortedEvent); _uniqueKeySortKeys.Remove(uniqueKey); _numberOfEvents--; removedEvents.Add(lastSortedEvent); _sortedEvents.Remove(lastKey); InternalHandleRemovedKey(lastKey, lastSortedEvent); } } } // If there are child views, fireStatementStopped Update method if (_optionalRankedRandomAccess != null) { _optionalRankedRandomAccess.Refresh(_sortedEvents, _numberOfEvents, _sortWindowSize); } if (HasViews) { EventBean[] expiredArr = null; if (!removedEvents.IsEmpty()) { expiredArr = removedEvents.ToArray(); } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().QViewIndicate(this, _rankWindowViewFactory.ViewName, newData, expiredArr); } UpdateChildren(newData, expiredArr); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().AViewIndicate(); } } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.Get().AViewProcessIRStream(); } }