From c7e965fc3dc6ffe01e6d4823d56f7b604fef6270 Mon Sep 17 00:00:00 2001 From: Terry Truong Date: Tue, 18 Oct 2022 19:44:04 +1100 Subject: Reduce event data after reaching a memory limit --- src/App.vue | 37 +++++++++++++++++++++++++++++++++++-- src/components/TimeLine.vue | 4 +++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/App.vue b/src/App.vue index cc71cfe..5bf6458 100644 --- a/src/App.vue +++ b/src/App.vue @@ -21,7 +21,8 @@ + @remove="onTimelineRemove(idx)" @state-chg="onTimelineChg($event, idx)" + @event-req="onEventReq" @event-display="onEventDisplay($event, idx)"/> @@ -101,6 +102,7 @@ function onTimelineRemove(idx: number){ // For storing and looking up events const eventTree: ShallowRef> = shallowRef(new RBTree(cmpHistEvent)); +let idToEvent: Map = new Map(); // For tracking ranges for which the server has no more events let exhaustedRanges = new RBTree(cmpDatePairs); function cmpDatePairs(datePair1: [HistDate, HistDate], datePair2: [HistDate, HistDate]){ @@ -163,6 +165,30 @@ function addExhaustedRange(startDate: HistDate, endDate: HistDate){ } exhaustedRanges.insert([startDate, endDate]); } +// For keeping event data under a memory limit +const EXCESS_EVENTS_THRESHOLD = 10000; +let displayedEvents: Map = new Map(); // Maps TimeLine IDs to IDs of displayed events +function onEventDisplay(eventIds: number[], timelineId: number){ + displayedEvents.set(timelineId, eventIds); +} +function reduceEvents(){ + // Get events to keep + let eventsToKeep: Map = new Map(); + for (let [, ids] of displayedEvents){ + for (let id of ids){ + eventsToKeep.set(id, idToEvent.get(id)!); + } + } + // Create new event tree + let newTree = new RBTree(cmpHistEvent); + for (let [, event] of eventsToKeep){ + newTree.insert(event); + } + // Replace old data + eventTree.value = newTree; + idToEvent = eventsToKeep; + exhaustedRanges.clear(); +} // For getting events from server const EVENT_REQ_LIMIT = 10; async function onEventReq(startDate: HistDate, endDate: HistDate){ @@ -197,7 +223,10 @@ async function onEventReq(startDate: HistDate, endDate: HistDate){ for (let eventObj of responseObj){ let event = jsonToHistEvent(eventObj); let success = eventTree.value.insert(event); - added = added || success; + if (success){ + added = true; + idToEvent.set(event.id, event); + } } // Notify components if new events were added if (added){ @@ -205,6 +234,10 @@ async function onEventReq(startDate: HistDate, endDate: HistDate){ } else { addExhaustedRange(startDate, endDate); // Mark as exhausted range } + // Check memory limit + if (eventTree.value.size > EXCESS_EVENTS_THRESHOLD){ + reduceEvents(); + } } // For resize handling diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue index 6c6b6fc..577413d 100644 --- a/src/components/TimeLine.vue +++ b/src/components/TimeLine.vue @@ -67,7 +67,7 @@ const props = defineProps({ initialState: {type: Object as PropType, required: true}, eventTree: {type: Object as PropType>, required: true}, }); -const emit = defineEmits(['remove', 'state-chg', 'event-req']); +const emit = defineEmits(['remove', 'state-chg', 'event-req', 'event-display']); // For size tracking const width = ref(0); @@ -285,6 +285,8 @@ const idToPos = computed(() => { // If more events could be displayed, notify parent if (map.size < 3 && !pendingReq){ emit('event-req', startDate.value, endDate.value); + } else { // Send displayed event IDs to parent + emit('event-display', [...idToEvent.value.keys()], ID); } pendingReq = true; // -- cgit v1.2.3