Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
dalyd committed Nov 10, 2016
2 parents abf4aa7 + 80570d3 commit 1d45284
Show file tree
Hide file tree
Showing 4 changed files with 415 additions and 37 deletions.
10 changes: 6 additions & 4 deletions benchrun.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,16 @@ def main():
args.includeFilter = '%'

# Print version info.
call([args.shellpath, "--norc", "--port", args.port, "--eval",
"print('db version: ' + db.version());"
call([args.shellpath, "--norc",
"--host", args.hostname, "--port", args.port,
"--eval", "print('db version: ' + db.version());"
" db.serverBuildInfo().gitVersion;"])
print("")


# Open a mongo shell subprocess and load necessary files.
mongo_proc = Popen([args.shellpath, "--norc", "--quiet", "--port", args.port], stdin=PIPE, stdout=PIPE)
mongo_proc = Popen([args.shellpath, "--norc", "--quiet",
"--host", args.hostname, "--port", args.port],
stdin=PIPE, stdout=PIPE)

# load test files
load_file_in_shell(mongo_proc, 'util/utils.js')
Expand Down
264 changes: 231 additions & 33 deletions testcases/pipelines.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function testCaseGenerator(options) {
pipeline.push({$skip: 1e9});
}
return {
tags: options.tags || ["aggregation", "regression"],
tags: ["aggregation", "regression"].concat(options.tags),
name: "Aggregation." + options.name,
pre: options.pre || populatorGenerator(nDocs,
options.indices || [],
Expand Down Expand Up @@ -208,41 +208,63 @@ tests.push(testCaseGenerator({
pipeline: [{$group: {_id: "$_idMod10", avg: {$avg: "$_id"}}}]
}));

tests.push(testCaseGenerator({
name: "Group.OneFieldReferencedOutOfMany",
docGenerator: function basicGroupDocGenerator(i) {
var doc = {_id: i, _idMod10: i % 10};
for (var j = 0; j < 100; j++) {
doc["field" + j] = i;
}
return doc;
},
pipeline: [{$group: {_id: "$_idMod10"}}]
}));

tests.push(testCaseGenerator({
name: "Limit",
nDocs: 500,
pipeline: [{$limit: 250}]
}));

// $lookup tests need two collections, so they use their own setup code.
/**
* Data population function used by the 'Lookup' and 'LookupViaGraphLookup' tests.
*/
function basicLookupPopulator(sourceCollection) {
const lookupCollName = sourceCollection.getName() + "_lookup";
let lookupCollection = sourceCollection.getDB()[lookupCollName];
const nDocs = 100;

sourceCollection.drop();
lookupCollection.drop();

let sourceBulk = sourceCollection.initializeUnorderedBulkOp();
let lookupBulk = lookupCollection.initializeUnorderedBulkOp();
for (let i = 0; i < nDocs; i++) {
sourceBulk.insert({_id: i, foreignKey: i});
lookupBulk.insert({_id: i});
}
sourceBulk.execute();
lookupBulk.execute();
}

/**
* Data cleanup function used by the 'Lookup' and 'LookupViaGraphLookup' tests.
*/
function basicLookupCleanup(sourceCollection) {
const lookupCollName = sourceCollection.getName() + "_lookup";
let lookupCollection = sourceCollection.getDB()[lookupCollName];
sourceCollection.drop();
lookupCollection.drop();
}

// Basic $lookup test. $lookup tests need two collections, so they use their own setup code.
tests.push(testCaseGenerator({
name: "Lookup",
// The setup function is only given one collection, but $lookup needs two. We'll treat the given
// one as the source collection, and create a second one with the name of the first plus
// '_lookup', which we'll use to look up from.
pre: function lookupPopulator(sourceCollection) {
var lookupCollName = sourceCollection.getName() + "_lookup";
var lookupCollection = sourceCollection.getDB()[lookupCollName];
var nDocs = 500;

sourceCollection.drop();
lookupCollection.drop();

var sourceBulk = sourceCollection.initializeUnorderedBulkOp();
var lookupBulk = lookupCollection.initializeUnorderedBulkOp();
for (var i = 0; i < nDocs; i++) {
sourceBulk.insert({_id: i, foreignKey: i});
lookupBulk.insert({_id: i});
}
sourceBulk.execute();
lookupBulk.execute();
},
post: function lookupPost(sourceCollection) {
var lookupCollName = sourceCollection.getName() + "_lookup";
var lookupCollection = sourceCollection.getDB()[lookupCollName];
sourceCollection.drop();
lookupCollection.drop();
},
pre: basicLookupPopulator,
post: basicLookupCleanup,
pipeline: [
{
$lookup: {
Expand All @@ -252,7 +274,27 @@ tests.push(testCaseGenerator({
as: "match"
}
}
]
],
tags: ["lookup"]
}));

// Mimics the basic 'Lookup' test using $graphLookup for comparison.
tests.push(testCaseGenerator({
name: "LookupViaGraphLookup",
pre: basicLookupPopulator,
post: basicLookupCleanup,
pipeline: [
{
$graphLookup: {
from: "#B_COLL_lookup",
startWith: "$foreignKey",
connectFromField: "foreignKey",
connectToField: "_id",
as: "match"
}
}
],
tags: ["lookup"]
}));

tests.push(testCaseGenerator({
Expand All @@ -263,7 +305,7 @@ tests.push(testCaseGenerator({
pre: function lookupPopulator(ordersCollection) {
var productCollName = ordersCollection.getName() + "_lookup";
var productsCollection = ordersCollection.getDB()[productCollName];
var nDocs = 500;
var nDocs = 20;

productsCollection.drop();
ordersCollection.drop();
Expand All @@ -277,7 +319,7 @@ tests.push(testCaseGenerator({
productsBulk.insert({_id: i});

// Each order will contain a random number of products in an array.
var nProducts = Random.randInt(100);
var nProducts = Random.randInt(10);
var products = [];
for (var p = 0; p < nProducts; p++) {
products.push({_id: Random.randInt(nDocs), quantity: Random.randInt(20)});
Expand Down Expand Up @@ -310,7 +352,118 @@ tests.push(testCaseGenerator({
as: "product"
}
}
]
],
tags: ["lookup"]
}));

tests.push(testCaseGenerator({
name: "GraphLookupSocialite",
pre: function socialitePopulator(userCollection) {
const followerCollName = userCollection.getName() + "_follower";
let followerCollection = userCollection.getDB()[followerCollName];

userCollection.drop();
followerCollection.drop();

const userDocs = [
{_id: "djw", fullname: "Darren", country: "Australia"},
{_id: "bmw", fullname: "Bob", country: "Germany"},
{_id: "jsr", fullname: "Jared", country: "USA"},
{_id: "ftr", fullname: "Frank", country: "Canada"},
{_id: "jhw", fullname: "James", country: "USA"},
{_id: "cxs", fullname: "Charlie", country: "USA"},
{_id: "sss", fullname: "Stephen", country: "Australia"},
{_id: "ada", fullname: "Adam", country: "Ireland"},
{_id: "mar", fullname: "Mark", country: "Ireland"},
];

let userBulk = userCollection.initializeUnorderedBulkOp();
userDocs.forEach(function(userDoc) {
userBulk.insert(userDoc);
});
userBulk.execute();

const followers = [
{_f: "djw", _t: "jsr"},
{_f: "jsr", _t: "bmw"},
{_f: "ftr", _t: "bmw"},
{_f: "jhw", _t: "bmw"},
{_f: "sss", _t: "jhw"},
{_f: "cxs", _t: "sss"},
{_f: "aaa", _t: "cxs"},
{_f: "djw", _t: "cxs"},
{_f: "djw", _t: "jhw"},
{_f: "djw", _t: "sss"},
{_f: "djw", _t: "ftr"},
{_f: "djw", _t: "bmw"},
{_f: "ada", _t: "mar"},
];

let followerBulk = followerCollection.initializeUnorderedBulkOp();
followers.forEach(function(follower) {
followerBulk.insert(follower);
});
followerBulk.execute();
},
post: function lookupPost(userCollection) {
const followerCollName = userCollection.getName() + "_follower";
let followerCollection = userCollection.getDB()[followerCollName];
userCollection.drop();
followerCollection.drop();
},
pipeline: [
{
$graphLookup: {
from: "#B_COLL_follower",
startWith: "$_id",
connectFromField: "_t",
connectToField: "_f",
as: "network"
}
},
{$unwind: "$network"},
{$project: {_id: "$network._t"}}
],
tags: ["lookup"]
}));

tests.push(testCaseGenerator({
name: "GraphLookupNeighbors",
pre: function neighborPopulator(sourceCollection) {
const neighborCollName = sourceCollection.getName() + "_neighbor";
let neighborCollection = sourceCollection.getDB()[neighborCollName];

sourceCollection.drop();
neighborCollection.drop();

let bulk = neighborCollection.initializeUnorderedBulkOp();
for (var i = 0; i < 100; i++) {
bulk.insert({_id: i, neighbors: [i - 1, i + 1]});
}
bulk.execute();

sourceCollection.insert({starting: 50});
},
post: function lookupPost(sourceCollection) {
const neighborCollName = sourceCollection.getName() + "_follower";
let neighborCollection = sourceCollection.getDB()[neighborCollName];
sourceCollection.drop();
neighborCollection.drop();
},
pipeline: [
{
$graphLookup: {
from: "#B_COLL_neighbor",
startWith: "$starting",
connectFromField: "neighbors",
connectToField: "_id",
maxDepth: 10,
depthField: "distence",
as: "integers"
}
}
],
tags: ["lookup"]
}));

tests.push(testCaseGenerator({
Expand All @@ -319,10 +472,55 @@ tests.push(testCaseGenerator({
docGenerator: function simpleMatchDocGenerator(i) {
return {_id: i};
},
// Add a $project stage before the $match stage to ensure the $match isn't pushed down to the
// query layer.
pipeline: [{$project: {_id: 0, _idTimes10: {$multiply: ["$_id", 10]}}},
{$match: {_idTimes10: {$lt: 2500}}}]
// Add a $skip stage before the $match stage to ensure the $match isn't pushed down to the query
// layer. A $skip of 0 will be optimized out, so we need to skip at least one.
pipeline: [{$skip: 1}, {$match: {_idTimes10: {$lt: 250}}}]
}));

/**
* Makes a document generator which creates a document with 50 fields with the same value, and a
* 'predicate' field set to 0 if 'i' is even and 1 otherwise.
*/
function docGenerator50FieldsOnePredicate(i) {
var doc = {};
for (var j = 0; j < 50; j++) {
doc["field" + j] = "placeholder kinda big";
}
doc.predicate = i % 2;
return doc;
}

tests.push(testCaseGenerator({
name: "MatchOneFieldFromBigDocument",
nDocs: 1000,
docGenerator: docGenerator50FieldsOnePredicate,
// Add a $skip stage before the $match stage to ensure the $match isn't pushed down to the query
// layer. A $skip of 0 will be optimized out, so we need to skip at least one.
pipeline: [{$skip: 1}, {$match: {predicate: {$eq: 0}}}]
}));

tests.push(testCaseGenerator({
name: "MatchManyFieldsFromBigDocument",
nDocs: 1000,
docGenerator: docGenerator50FieldsOnePredicate,
// Add a $skip stage before the $match stage to ensure the $match isn't pushed down to the
// query layer. A $skip of 0 will be optimized out, so we need to skip at least one.
pipeline: [
{$skip: 1},
{$match: {
predicate: {$eq: 0},
// The following are present just to increase the number of fields we need to serialize
// to BSON to perform the match.
field0: {$type: "string"},
field1: {$type: "string"},
field2: {$type: "string"},
field10: {$type: "string"},
field25: {$type: "string"},
field40: {$type: "string"},
field48: {$type: "string"},
field49: {$type: "string"},
}}
]
}));

tests.push(testCaseGenerator({
Expand Down
46 changes: 46 additions & 0 deletions testcases/simple_insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,49 @@ tests.push( { name: "Insert.JustNumIndexed",
{ x: { "#SEQ_INT":
{ seq_id: 0, start: 0, step: 1, unique: true } } } }
] } );

/*
* Setup: Create an empty collection with a simple default collation and index field 'a'.
*
* Test: Repeatedly insert an indexed 10 character string.
*/
tests.push( { name: "InsertIndexedStringsSimpleCollation",
tags: ['insert','indexed','regression','collation'],
pre: function( collection ) {
var testDB = collection.getDB();
var collName = collection.getName();
collection.drop();
testDB.createCollection(collName, { collation: { locale: "simple" } } );
collection.ensureIndex( { a: 1 } );
},
ops: [
{ op: "insert", doc: { a: { "#RAND_STRING": [10] } } }
] } );

/*
* Setup: Create an empty collection with a non-simple default collation and index field 'a'. We set
* several collation options in an attempt to make the collation processing in ICU more expensive.
*
* Test: Repeatedly insert an indexed 10 character string.
*
* Comparing this test against InsertIndexedStringsSimpleCollation should indicate the overhead
* associated with generating index keys for an index with a non-simple collation.
*/
tests.push( { name: "InsertIndexedStringsNonSimpleCollation",
tags: ['insert','indexed','regression','collation'],
pre: function( collection ) {
var testDB = collection.getDB();
var collName = collection.getName();
collection.drop();
var myCollation = {
locale : "en",
strength : 5,
backwards : true,
normalization : true,
};
testDB.createCollection(collName, { collation: myCollation } );
collection.ensureIndex( { a: 1 } );
},
ops: [
{ op: "insert", doc: { a: { "#RAND_STRING": [10] } } }
] } );
Loading

0 comments on commit 1d45284

Please sign in to comment.