/** * This file tests the top-chunk optimization logic in splitChunk command. Whenever a chunk is * split, the shouldMigrate field should be set if the extreme chunk has only a single document, * where extreme chunk is defined as the chunk containing either the upper or lower bound of the * entire shard key space. */ (function() { 'use strict'; var st = new ShardingTest({shards: 1}); var testDB = st.s.getDB('test'); assert.commandWorked(testDB.adminCommand({enableSharding: 'test'})); var callSplit = function(db, minKey, maxKey, splitPoints) { var res = st.s.adminCommand({getShardVersion: "test.user"}); assert.commandWorked(res); return db.runCommand({ splitChunk: 'test.user', from: st.shard0.shardName, min: minKey, max: maxKey, keyPattern: {x: 1}, splitKeys: splitPoints, epoch: res.versionEpoch, }); }; var tests = [ // // Lower extreme chunk tests. // // All chunks have 1 doc. // // Expected doc counts for new chunks: // [ MinKey, -2 ): 1 // [ -2, -1 ): 1 // [ -1, 0): 1 // function(db) { var res = callSplit(db, {x: MinKey}, {x: 0}, [{x: -2}, {x: -1}]); assert.commandWorked(res); assert.neq(res.shouldMigrate, null, tojson(res)); assert(bsonWoCompare(res.shouldMigrate.min, {x: MinKey}) == 0, tojson(res.shouldMigrate.min)); assert(bsonWoCompare(res.shouldMigrate.max, {x: -2}) == 0, tojson(res.shouldMigrate.max)); }, // One chunk has single doc, extreme doesn't. // // Expected doc counts for new chunks: // [ MinKey, -1 ): 2 // [ -1, 0): 1 // function(db) { var res = callSplit(db, {x: MinKey}, {x: 0}, [{x: -1}]); assert.commandWorked(res); assert.eq(res.shouldMigrate, null, tojson(res)); }, // Only extreme has single doc. // // Expected doc counts for new chunks: // [ MinKey, -2 ): 1 // [ -2, 0): 2 // function(db) { var res = callSplit(db, {x: MinKey}, {x: 0}, [{x: -2}]); assert.commandWorked(res); assert.neq(res.shouldMigrate, null, tojson(res)); assert(bsonWoCompare(res.shouldMigrate.min, {x: MinKey}) == 0, tojson(res.shouldMigrate.min)); assert(bsonWoCompare(res.shouldMigrate.max, {x: -2}) == 0, tojson(res.shouldMigrate.max)); }, // // Upper extreme chunk tests. // // All chunks have 1 doc. // // Expected doc counts for new chunks: // [ 0, 1 ): 1 // [ 1, 2 ): 1 // [ 2, MaxKey): 1 // function(db) { var res = callSplit(db, {x: 0}, {x: MaxKey}, [{x: 1}, {x: 2}]); assert.commandWorked(res); assert.neq(res.shouldMigrate, null, tojson(res)); assert(bsonWoCompare(res.shouldMigrate.min, {x: 2}) == 0, tojson(res.shouldMigrate.min)); assert(bsonWoCompare(res.shouldMigrate.max, {x: MaxKey}) == 0, tojson(res.shouldMigrate.max)); }, // One chunk has single doc, extreme doesn't. // // Expected doc counts for new chunks: // [ 0, 1 ): 1 // [ 1, MaxKey): 2 // function(db) { var res = callSplit(db, {x: 0}, {x: MaxKey}, [{x: 1}]); assert.commandWorked(res); assert.eq(res.shouldMigrate, null, tojson(res)); }, // Only extreme has single doc. // // Expected doc counts for new chunks: // [ 0, 2 ): 2 // [ 2, MaxKey): 1 // function(db) { var res = callSplit(db, {x: 0}, {x: MaxKey}, [{x: 2}]); assert.commandWorked(res); assert.neq(res.shouldMigrate, null, tojson(res)); assert(bsonWoCompare(res.shouldMigrate.min, {x: 2}) == 0, tojson(res.shouldMigrate.min)); assert(bsonWoCompare(res.shouldMigrate.max, {x: MaxKey}) == 0, tojson(res.shouldMigrate.max)); }, ]; tests.forEach(function(test) { // setup assert.commandWorked(testDB.adminCommand({shardCollection: 'test.user', key: {x: 1}})); assert.commandWorked(testDB.adminCommand({split: 'test.user', middle: {x: 0}})); for (var x = -3; x < 3; x++) { testDB.user.insert({x: x}); } // run test test(st.rs0.getPrimary().getDB('admin')); // teardown testDB.user.drop(); }); st.stop(); })();