From c7e965fc3dc6ffe01e6d4823d56f7b604fef6270 Mon Sep 17 00:00:00 2001
From: Terry Truong <terry06890@gmail.com>
Date: Tue, 18 Oct 2022 19:44:04 +1100
Subject: Reduce event data after reaching a memory limit

---
 src/App.vue | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

(limited to 'src/App.vue')

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 @@
 		<time-line v-for="(state, idx) in timelines" :key="state.id"
 			:vert="vert" :initialState="state" :eventTree="eventTree"
 			class="grow basis-full min-h-0 outline outline-1"
-			@remove="onTimelineRemove(idx)" @state-chg="onTimelineChg($event, idx)" @event-req="onEventReq"/>
+			@remove="onTimelineRemove(idx)" @state-chg="onTimelineChg($event, idx)"
+			@event-req="onEventReq" @event-display="onEventDisplay($event, idx)"/>
 		<base-line :vert="vert" :timelines="timelines"/>
 	</div>
 </div>
@@ -101,6 +102,7 @@ function onTimelineRemove(idx: number){
 
 // For storing and looking up events
 const eventTree: ShallowRef<RBTree<HistEvent>> = shallowRef(new RBTree(cmpHistEvent));
+let idToEvent: Map<number, HistEvent> = 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<number, number[]> = 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<number, HistEvent> = 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
-- 
cgit v1.2.3

