Skip to content

Commit 5241b06

Browse files
committed
Always return the smallest element when there is more than one match.
1 parent 07f6b81 commit 5241b06

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

lib/source-map/binary-search.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,23 @@ define(function (require, exports, module) {
9595
return -1;
9696
}
9797

98-
return recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare,
99-
aBias || exports.GREATEST_LOWER_BOUND);
98+
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
99+
aCompare, aBias || exports.GREATEST_LOWER_BOUND);
100+
if (index < 0) {
101+
return -1;
102+
}
103+
104+
// We have found either the exact element, or the next-closest element than
105+
// the one we are searching for. However, there may be more than one such
106+
// element. Make sure we always return the smallest of these.
107+
while (index - 1 >= 0) {
108+
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
109+
break;
110+
}
111+
--index;
112+
}
113+
114+
return index;
100115
};
101116

102117
});

lib/source-map/util.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ define(function (require, exports, module) {
261261
return cmp;
262262
}
263263

264-
cmp = strcmp(mappingA.name, mappingB.name);
264+
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
265265
if (cmp) {
266266
return cmp;
267267
}
@@ -271,7 +271,7 @@ define(function (require, exports, module) {
271271
return cmp;
272272
}
273273

274-
return mappingA.generatedColumn - mappingB.generatedColumn;
274+
return strcmp(mappingA.name, mappingB.name);
275275
};
276276
exports.compareByOriginalPositions = compareByOriginalPositions;
277277

test/source-map/test-binary-search.js

+16
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,20 @@ define(function (require, exports, module) {
8383
binarySearch.LEAST_UPPER_BOUND)], 20);
8484
};
8585

86+
exports['test multiple matches'] = function (assert, util) {
87+
var needle = 5;
88+
var haystack = [1, 1, 2, 5, 5, 5, 13, 21];
89+
90+
assert.equal(binarySearch.search(needle, haystack, numberCompare,
91+
binarySearch.LEAST_UPPER_BOUND), 3);
92+
};
93+
94+
exports['test multiple matches at the beginning'] = function (assert, util) {
95+
var needle = 1;
96+
var haystack = [1, 1, 2, 5, 5, 5, 13, 21];
97+
98+
assert.equal(binarySearch.search(needle, haystack, numberCompare,
99+
binarySearch.LEAST_UPPER_BOUND), 0);
100+
};
101+
86102
});

0 commit comments

Comments
 (0)