Skip to content

Commit a92fa72

Browse files
authored
Merge pull request #8889 from CesiumGS/remove-trailing-references
Remove trailing references from ManagedArray and Heap
2 parents 617e5ed + 72df481 commit a92fa72

File tree

4 files changed

+124
-9
lines changed

4 files changed

+124
-9
lines changed

Source/Core/Heap.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,20 @@ Object.defineProperties(Heap.prototype, {
6565
return this._maximumLength;
6666
},
6767
set: function (value) {
68-
this._maximumLength = value;
69-
if (this._length > value && value > 0) {
68+
//>>includeStart('debug', pragmas.debug);
69+
Check.typeOf.number.greaterThanOrEquals("maximumLength", value, 0);
70+
//>>includeEnd('debug');
71+
var originalLength = this._length;
72+
if (value < originalLength) {
73+
var array = this._array;
74+
// Remove trailing references
75+
for (var i = value; i < originalLength; ++i) {
76+
array[i] = undefined;
77+
}
7078
this._length = value;
71-
this._array.length = value;
79+
array.length = value;
7280
}
81+
this._maximumLength = value;
7382
},
7483
},
7584

@@ -211,6 +220,7 @@ Heap.prototype.pop = function (index) {
211220
var root = array[index];
212221
swap(array, index, --this._length);
213222
this.heapify(index);
223+
array[this._length] = undefined; // Remove trailing reference
214224
return root;
215225
};
216226

Source/Core/ManagedArray.js

+21-6
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,20 @@ Object.defineProperties(ManagedArray.prototype, {
2929
return this._length;
3030
},
3131
set: function (length) {
32-
this._length = length;
33-
if (length > this._array.length) {
34-
this._array.length = length;
32+
//>>includeStart('debug', pragmas.debug);
33+
Check.typeOf.number.greaterThanOrEquals("length", length, 0);
34+
//>>includeEnd('debug');
35+
var array = this._array;
36+
var originalLength = this._length;
37+
if (length < originalLength) {
38+
// Remove trailing references
39+
for (var i = length; i < originalLength; ++i) {
40+
array[i] = undefined;
41+
}
42+
} else if (length > array.length) {
43+
array.length = length;
3544
}
45+
this._length = length;
3646
},
3747
},
3848

@@ -74,7 +84,7 @@ ManagedArray.prototype.set = function (index, element) {
7484
Check.typeOf.number("index", index);
7585
//>>includeEnd('debug');
7686

77-
if (index >= this.length) {
87+
if (index >= this._length) {
7888
this.length = index + 1;
7989
}
8090
this._array[index] = element;
@@ -105,7 +115,12 @@ ManagedArray.prototype.push = function (element) {
105115
* @returns {*} The last element in the array.
106116
*/
107117
ManagedArray.prototype.pop = function () {
108-
return this._array[--this.length];
118+
if (this._length === 0) {
119+
return undefined;
120+
}
121+
var element = this._array[this._length - 1];
122+
--this.length;
123+
return element;
109124
};
110125

111126
/**
@@ -142,7 +157,7 @@ ManagedArray.prototype.resize = function (length) {
142157
* @param {Number} [length] The length.
143158
*/
144159
ManagedArray.prototype.trim = function (length) {
145-
length = defaultValue(length, this.length);
160+
length = defaultValue(length, this._length);
146161
this._array.length = length;
147162
};
148163
export default ManagedArray;

Specs/Core/HeapSpec.js

+46
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ import { Heap } from "../../Source/Cesium.js";
33
describe("Core/Heap", function () {
44
var length = 100;
55

6+
function expectTrailingReferenceToBeRemoved(heap) {
7+
var array = heap._array;
8+
var length = heap._length;
9+
var reservedLength = array.length;
10+
for (var i = length; i < reservedLength; ++i) {
11+
expect(array[i]).toBeUndefined();
12+
}
13+
}
14+
615
function checkHeap(heap, comparator) {
716
var array = heap.internalArray;
817
var pass = true;
@@ -90,6 +99,34 @@ describe("Core/Heap", function () {
9099
expect(pass).toBe(true);
91100
});
92101

102+
it("pop removes trailing references", function () {
103+
var heap = new Heap({
104+
comparator: comparator,
105+
});
106+
107+
for (var i = 0; i < 10; ++i) {
108+
heap.insert(Math.random());
109+
}
110+
111+
heap.pop();
112+
heap.pop();
113+
114+
expectTrailingReferenceToBeRemoved(heap);
115+
});
116+
117+
it("setting maximum length less than current length removes trailing references", function () {
118+
var heap = new Heap({
119+
comparator: comparator,
120+
});
121+
122+
for (var i = 0; i < 10; ++i) {
123+
heap.insert(Math.random());
124+
}
125+
126+
heap.maximumLength = 5;
127+
expectTrailingReferenceToBeRemoved(heap);
128+
});
129+
93130
it("insert returns the removed element when maximumLength is set", function () {
94131
var heap = new Heap({
95132
comparator: comparator,
@@ -170,4 +207,13 @@ describe("Core/Heap", function () {
170207
currentId = element.id;
171208
}
172209
});
210+
211+
it("maximumLength setter throws if length is less than 0", function () {
212+
var heap = new Heap({
213+
comparator: comparator,
214+
});
215+
expect(function () {
216+
heap.maximumLength = -1;
217+
}).toThrowDeveloperError();
218+
});
173219
});

Specs/Core/ManagedArraySpec.js

+44
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import { ManagedArray } from "../../Source/Cesium.js";
22

33
describe("Core/ManagedArray", function () {
4+
function expectTrailingReferenceToBeRemoved(managedArray) {
5+
var array = managedArray._array;
6+
var length = managedArray._length;
7+
var reservedLength = array.length;
8+
for (var i = length; i < reservedLength; ++i) {
9+
expect(array[i]).toBeUndefined();
10+
}
11+
}
12+
413
it("constructor has expected default values", function () {
514
var array = new ManagedArray();
615
expect(array.length).toEqual(0);
@@ -42,6 +51,13 @@ describe("Core/ManagedArray", function () {
4251
}).toThrowDeveloperError();
4352
});
4453

54+
it("length setter throws if length is less than 0", function () {
55+
var array = new ManagedArray();
56+
expect(function () {
57+
array.length = -1;
58+
}).toThrowDeveloperError();
59+
});
60+
4561
it("set resizes array", function () {
4662
var array = new ManagedArray();
4763
array.set(0, "a");
@@ -90,6 +106,24 @@ describe("Core/ManagedArray", function () {
90106
}
91107
});
92108

109+
it("pop removes trailing references", function () {
110+
var length = 10;
111+
var array = new ManagedArray(length);
112+
array.set(0, Math.random());
113+
array.set(1, Math.random());
114+
array.set(2, Math.random());
115+
array.pop();
116+
array.pop();
117+
expectTrailingReferenceToBeRemoved(array);
118+
});
119+
120+
it("pop returns undefined if array is empty", function () {
121+
var array = new ManagedArray();
122+
array.push(1);
123+
expect(array.pop()).toBe(1);
124+
expect(array.pop()).toBeUndefined();
125+
});
126+
93127
it("reserve throws if length is less than 0", function () {
94128
var array = new ManagedArray();
95129
expect(function () {
@@ -130,6 +164,16 @@ describe("Core/ManagedArray", function () {
130164
expect(array.length).toEqual(5);
131165
});
132166

167+
it("resize removes trailing references", function () {
168+
var length = 10;
169+
var array = new ManagedArray(length);
170+
array.set(0, Math.random());
171+
array.set(1, Math.random());
172+
array.set(2, Math.random());
173+
array.resize(1);
174+
expectTrailingReferenceToBeRemoved(array);
175+
});
176+
133177
it("trim", function () {
134178
var array = new ManagedArray(2);
135179
array.reserve(10);

0 commit comments

Comments
 (0)