summaryrefslogtreecommitdiff
path: root/jstests/aggregation/bugs/server4656.js
blob: cbb07f81ea55dd9bc8e434fe6d69ebf3d7e9ac16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SERVER-4656 optimize $sort followed by $limit

var c = db.c;
c.drop();

NUM_OBJS = 100;

var randoms = {};
function generateRandom() {
    // we want unique randoms since $sort isn't guaranteed stable
    var random;
    do {
        random = Math.round(Math.random() * 1000 * NUM_OBJS);
    } while (randoms[random]);
    randoms[random] = true;
    return random;
}

for (var i = 0; i < NUM_OBJS; i++) {
    c.insert({inc: i, dec: NUM_OBJS-i, rnd: generateRandom()});
}

var inc_sorted = c.aggregate({$sort: {inc:1}}).toArray();
var dec_sorted = c.aggregate({$sort: {dec:1}}).toArray();
var rnd_sorted = c.aggregate({$sort: {rnd:1}}).toArray();

function test(limit, direction) {
    try {
        var res_inc = c.aggregate({$sort: {inc:direction}}, {$limit:limit}).toArray();
        var res_dec = c.aggregate({$sort: {dec:direction}}, {$limit:limit}).toArray();
        var res_rnd = c.aggregate({$sort: {rnd:direction}}, {$limit:limit}).toArray();

        var expectedLength = Math.min(limit, NUM_OBJS) ;

        assert.eq(res_inc.length, expectedLength);
        assert.eq(res_dec.length, expectedLength);
        assert.eq(res_rnd.length, expectedLength);

        if (direction > 0) {
            for (var i = 0; i < expectedLength; i++) {
                assert.eq(res_inc[i], inc_sorted[i]);
                assert.eq(res_dec[i], dec_sorted[i]);
                assert.eq(res_rnd[i], rnd_sorted[i]);
            }
        }
        else {
            for (var i = 0; i < expectedLength; i++) {
                assert.eq(res_inc[i], inc_sorted[NUM_OBJS - 1 - i]);
                assert.eq(res_dec[i], dec_sorted[NUM_OBJS - 1 - i]);
                assert.eq(res_rnd[i], rnd_sorted[NUM_OBJS - 1 - i]);
            }
        }
    }
    catch (e) {
        print("failed with limit=" + limit + " direction= " + direction);
        throw e;
    }
}

test(1,  1);
test(1, -1);
test(10,  1);
test(10, -1);
test(50,  1);
test(50, -1);
test(NUM_OBJS,  1);
test(NUM_OBJS, -1);
test(NUM_OBJS + 10,  1);
test(NUM_OBJS + 10, -1);