From d585bd7ac63d7d2b56d9a8a8fbbdb92a39a084e0 Mon Sep 17 00:00:00 2001 From: Valentin Sawadski Date: Tue, 1 Mar 2022 19:20:23 +0000 Subject: [PATCH] Fix: Memory Leak in ItemTracked Closes #38 --- ItemTracked.js | 27 +++++++++++++++++--- spec/ItemTracked.spec.js | 54 +++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/ItemTracked.js b/ItemTracked.js index c1e78b6..5da4f87 100644 --- a/ItemTracked.js +++ b/ItemTracked.js @@ -12,6 +12,9 @@ var computeVelocityVector = require('./utils').computeVelocityVector // "name": "car" // } +/** The maximum length of the item history. */ +exports.ITEM_HISTORY_MAX_LENGTH = 15; + // Use a simple incremental unique id for the display var idDisplay = 0; @@ -48,6 +51,9 @@ exports.ItemTracked = function(properties, frameNb, unMatchedFramesTolerance, fa h: properties.h, confidence: properties.confidence }); + if(itemTracked.itemHistory.length >= exports.ITEM_HISTORY_MAX_LENGTH) { + itemTracked.itemHistory.shift(); + } itemTracked.velocity = { dx: 0, dy: 0 @@ -79,6 +85,9 @@ exports.ItemTracked = function(properties, frameNb, unMatchedFramesTolerance, fa h: this.h, confidence: this.confidence }); + if(itemTracked.itemHistory.length >= exports.ITEM_HISTORY_MAX_LENGTH) { + itemTracked.itemHistory.shift(); + } this.name = properties.name; if(this.nameCount[properties.name]) { this.nameCount[properties.name]++; @@ -124,6 +133,9 @@ exports.ItemTracked = function(properties, frameNb, unMatchedFramesTolerance, fa h: this.h, confidence: this.confidence }); + if(itemTracked.itemHistory.length >= exports.ITEM_HISTORY_MAX_LENGTH) { + itemTracked.itemHistory.shift(); + } this.x = this.x + this.velocity.dx this.y = this.y + this.velocity.dy } @@ -142,11 +154,18 @@ exports.ItemTracked = function(properties, frameNb, unMatchedFramesTolerance, fa } // Velocity vector based on the last 15 frames itemTracked.updateVelocityVector = function() { - var AVERAGE_NBFRAME = 15; - if(this.itemHistory.length <= AVERAGE_NBFRAME) { - return computeVelocityVector(this.itemHistory[0], this.itemHistory[this.itemHistory.length - 1], this.itemHistory.length); + if(exports.ITEM_HISTORY_MAX_LENGTH <= 2) { + return { dx: undefined, dy: undefined, } + } + + if(this.itemHistory.length <= exports.ITEM_HISTORY_MAX_LENGTH) { + const start = this.itemHistory[0]; + const end = this.itemHistory[this.itemHistory.length - 1]; + return computeVelocityVector(start, end, this.itemHistory.length); } else { - return computeVelocityVector(this.itemHistory[this.itemHistory.length - AVERAGE_NBFRAME], this.itemHistory[this.itemHistory.length - 1], AVERAGE_NBFRAME); + const start = this.itemHistory[this.itemHistory.length - exports.ITEM_HISTORY_MAX_LENGTH]; + const end = this.itemHistory[this.itemHistory.length - 1]; + return computeVelocityVector(start, end, exports.ITEM_HISTORY_MAX_LENGTH); } } diff --git a/spec/ItemTracked.spec.js b/spec/ItemTracked.spec.js index 3044bd3..3ad628a 100644 --- a/spec/ItemTracked.spec.js +++ b/spec/ItemTracked.spec.js @@ -1,30 +1,54 @@ const ItemTracked = require('../ItemTracked'); describe("ItemTracked", function () { + const properties = { + x: null, + y: null, + w: null, + h: null, + name: "dummy", + confidence: null + }; + describe("idDisplay", function () { - const properties = { - x: null, - y: null, - w: null, - h: null, - name: "dummy", - confidence: null - }; const item1 = ItemTracked.ItemTracked(properties); const item2 = ItemTracked.ItemTracked(properties); - it('starts at 0', function() { - expect(item1.idDisplay).toBe(0); + it('starts at 0', function () { + expect(item1.idDisplay).toBe(0); }); - it('icrements IDs', function() { + it('icrements IDs', function () { expect(item1.idDisplay).toBeLessThan(item2.idDisplay); }); - it('resets IDs', function() { - ItemTracked.reset(); - const item3 = ItemTracked.ItemTracked(properties); - expect(item3.idDisplay).toBe(0); + it('resets IDs', function () { + ItemTracked.reset(); + const item3 = ItemTracked.ItemTracked(properties); + expect(item3.idDisplay).toBe(0); + }); + }); + + describe('itemHistory', () => { + it('stops at max length', () => { + const item1 = ItemTracked.ItemTracked(properties); + for (var i = 0; i < ItemTracked.ITEM_HISTORY_MAX_LENGTH + 2; i++) { + item1.update(properties, i); + expect(item1.itemHistory.length).toBeLessThanOrEqual(ItemTracked.ITEM_HISTORY_MAX_LENGTH); + } + }); + + it('does not store history', () => { + const originalItemHistoryMaxLen = ItemTracked.ITEM_HISTORY_MAX_LENGTH; + ItemTracked.ITEM_HISTORY_MAX_LENGTH = 0; + const item1 = ItemTracked.ItemTracked(properties); + + for (var i = 0; i < ItemTracked.ITEM_HISTORY_MAX_LENGTH + 2; i++) { + item1.update(properties, i); + expect(item1.itemHistory.length).toBe(ItemTracked.ITEM_HISTORY_MAX_LENGTH); + } + + ItemTracked.ITEM_HISTORY_MAX_LENGTH = originalItemHistoryMaxLen; }); }); });