Skip to content

Commit

Permalink
Revert support for sorting NaN values.
Browse files Browse the repository at this point in the history
  • Loading branch information
jasondavies committed Apr 10, 2013
1 parent ae994e8 commit edfaaed
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 82 deletions.
33 changes: 9 additions & 24 deletions crossfilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,15 @@ function bisect_by(f) {
// present in a, the insertion point will be before (to the left of) any
// existing entries. The return value is suitable for use as the first
// argument to `array.splice` assuming that a is already sorted.
// Incomparable values such as NaN and undefined are assumed to be at the end
// of the array.
//
// The returned insertion point i partitions the array a into two halves so
// that all v < x for v in a[lo:i] for the left side and all v >= x for v in
// a[i:hi] for the right side.
function bisectLeft(a, x, lo, hi) {
while (lo < hi) {
var mid = lo + hi >>> 1,
y = f(a[mid]);
if (x <= y || !(y <= y)) hi = mid;
else lo = mid + 1;
var mid = lo + hi >>> 1;
if (f(a[mid]) < x) lo = mid + 1;
else hi = mid;
}
return lo;
}
Expand All @@ -47,9 +44,8 @@ function bisect_by(f) {
// a[i:hi] for the right side.
function bisectRight(a, x, lo, hi) {
while (lo < hi) {
var mid = lo + hi >>> 1,
y = f(a[mid]);
if (x < y || !(y <= y)) hi = mid;
var mid = lo + hi >>> 1;
if (x < f(a[mid])) hi = mid;
else lo = mid + 1;
}
return lo;
Expand Down Expand Up @@ -147,7 +143,7 @@ function insertionsort_by(f) {

function insertionsort(a, lo, hi) {
for (var i = lo + 1; i < hi; ++i) {
for (var j = i, t = a[i], x = f(t), y; j > lo && ((y = f(a[j - 1])) > x || !(y <= y)); --j) {
for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) {
a[j] = a[j - 1];
}
a[j] = t;
Expand All @@ -174,17 +170,6 @@ function quicksort_by(f) {
}

function quicksort(a, lo, hi) {
// First move NaN and undefined to the end.
var x, y;
while (lo < hi && !((x = f(a[hi - 1])) <= x)) hi--;
for (var i = hi; --i >= lo; ) {
x = f(y = a[i]);
if (!(x <= x)) {
a[i] = a[--hi];
a[hi] = y;
}
}

// Compute the two pivots by looking at 5 elements.
var sixth = (hi - lo) / 6 | 0,
i1 = lo + sixth,
Expand Down Expand Up @@ -892,8 +877,8 @@ function crossfilter() {
// Get the first old key (x0 of g0), if it exists.
if (k0) x0 = (g0 = oldGroups[0]).key;

// Find the first new key (x1).
x1 = key(newValues[i1]);
// Find the first new key (x1), skipping NaN keys.
while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1;

// While new keys remain…
while (i1 < n1) {
Expand All @@ -917,7 +902,7 @@ function crossfilter() {

// Add any selected records belonging to the added group, while
// advancing the new key and populating the associated group index.
while (x1 <= x || !(x1 <= x1) && !(x <= x)) {
while (!(x1 > x)) {
groupIndex[j = newIndex[i1] + n0] = k;
if (!(filters[j] & zero)) g.value = add(g.value, data[j]);
if (++i1 >= n1) break;
Expand Down
2 changes: 1 addition & 1 deletion crossfilter.min.js

Large diffs are not rendered by default.

14 changes: 5 additions & 9 deletions src/bisect.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@ function bisect_by(f) {
// present in a, the insertion point will be before (to the left of) any
// existing entries. The return value is suitable for use as the first
// argument to `array.splice` assuming that a is already sorted.
// Incomparable values such as NaN and undefined are assumed to be at the end
// of the array.
//
// The returned insertion point i partitions the array a into two halves so
// that all v < x for v in a[lo:i] for the left side and all v >= x for v in
// a[i:hi] for the right side.
function bisectLeft(a, x, lo, hi) {
while (lo < hi) {
var mid = lo + hi >>> 1,
y = f(a[mid]);
if (x <= y || !(y <= y)) hi = mid;
else lo = mid + 1;
var mid = lo + hi >>> 1;
if (f(a[mid]) < x) lo = mid + 1;
else hi = mid;
}
return lo;
}
Expand All @@ -34,9 +31,8 @@ function bisect_by(f) {
// a[i:hi] for the right side.
function bisectRight(a, x, lo, hi) {
while (lo < hi) {
var mid = lo + hi >>> 1,
y = f(a[mid]);
if (x < y || !(y <= y)) hi = mid;
var mid = lo + hi >>> 1;
if (x < f(a[mid])) hi = mid;
else lo = mid + 1;
}
return lo;
Expand Down
6 changes: 3 additions & 3 deletions src/crossfilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ function crossfilter() {
// Get the first old key (x0 of g0), if it exists.
if (k0) x0 = (g0 = oldGroups[0]).key;

// Find the first new key (x1).
x1 = key(newValues[i1]);
// Find the first new key (x1), skipping NaN keys.
while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1;

// While new keys remain…
while (i1 < n1) {
Expand All @@ -388,7 +388,7 @@ function crossfilter() {

// Add any selected records belonging to the added group, while
// advancing the new key and populating the associated group index.
while (x1 <= x || !(x1 <= x1) && !(x <= x)) {
while (!(x1 > x)) {
groupIndex[j = newIndex[i1] + n0] = k;
if (!(filters[j] & zero)) g.value = add(g.value, data[j]);
if (++i1 >= n1) break;
Expand Down
2 changes: 1 addition & 1 deletion src/insertionsort.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function insertionsort_by(f) {

function insertionsort(a, lo, hi) {
for (var i = lo + 1; i < hi; ++i) {
for (var j = i, t = a[i], x = f(t), y; j > lo && ((y = f(a[j - 1])) > x || !(y <= y)); --j) {
for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) {
a[j] = a[j - 1];
}
a[j] = t;
Expand Down
11 changes: 0 additions & 11 deletions src/quicksort.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,6 @@ function quicksort_by(f) {
}

function quicksort(a, lo, hi) {
// First move NaN and undefined to the end.
var x, y;
while (lo < hi && !((x = f(a[hi - 1])) <= x)) hi--;
for (var i = hi; --i >= lo; ) {
x = f(y = a[i]);
if (!(x <= x)) {
a[i] = a[--hi];
a[hi] = y;
}
}

// Compute the two pivots by looking at 5 elements.
var sixth = (hi - lo) / 6 | 0,
i1 = lo + sixth,
Expand Down
20 changes: 0 additions & 20 deletions test/bisect-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,6 @@ suite.addBatch({
assert.equal(bisect(array, 5, 2, 3), 3);
assert.equal(bisect(array, 6, 2, 3), 3);
},
"ignores NaNs at end of array": function(bisect) {
var array = [1, 2, NaN, NaN, NaN];
assert.equal(bisect(array, 0, 0, 5), 0);
assert.equal(bisect(array, 1, 0, 5), 0);
assert.equal(bisect(array, 2, 0, 5), 1);
assert.equal(bisect(array, 3, 0, 5), 2);
assert.equal(bisect(array, 4, 0, 5), 2);
assert.equal(bisect(array, 5, 0, 5), 2);
assert.equal(bisect(array, 6, 0, 5), 2);
},
"large arrays": function(bisect) {
var array = [],
i = 1 << 30;
Expand Down Expand Up @@ -195,16 +185,6 @@ suite.addBatch({
assert.equal(bisect(array, 5, 2, 3), 3);
assert.equal(bisect(array, 6, 2, 3), 3);
},
"ignores NaNs at end of array": function(bisect) {
var array = [1, 2, 3, NaN, NaN];
assert.equal(bisect(array, 0, 0, 5), 0);
assert.equal(bisect(array, 1, 0, 5), 1);
assert.equal(bisect(array, 2, 0, 5), 2);
assert.equal(bisect(array, 3, 0, 5), 3);
assert.equal(bisect(array, 4, 0, 5), 3);
assert.equal(bisect(array, 5, 0, 5), 3);
assert.equal(bisect(array, 6, 0, 5), 3);
},
"large arrays": function(bisect) {
var array = [],
i = 1 << 30;
Expand Down
13 changes: 0 additions & 13 deletions test/sort-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,6 @@ function batch(sort, extras) {
assert.strictEqual(untypedArray.sort(ascending), untypedArray);
for (var i = 0; i < n; i++) untypedActual[i] = typedArray[i];
assert.deepEqual(untypedActual, untypedArray);
},
"can sort a smallish array containing a mix of finite floats and NaNs quickly": function(sort) {
var n = 1e3,
array = new Array(n),
start,
duration;
for (var i = 0; i < n >> 2; i++) array[i] = NaN; // or undefined
for (; i < n; i++) array[i] = Math.random();
start = Date.now();
sort(array, 0, n);
duration = Date.now() - start;
assert.lesser(duration, 500);
for (var i = 1; i < n; i++) assert(array[i - 1] <= array[i] || isNaN(array[i]));
}
};
for (var key in extras) batch[key] = extras[key];
Expand Down

0 comments on commit edfaaed

Please sign in to comment.