diff options
Diffstat (limited to 'jstests/splitvector.js')
-rw-r--r-- | jstests/splitvector.js | 144 |
1 files changed, 129 insertions, 15 deletions
diff --git a/jstests/splitvector.js b/jstests/splitvector.js index 8d86319..da93486 100644 --- a/jstests/splitvector.js +++ b/jstests/splitvector.js @@ -11,7 +11,7 @@ // e.g. 20000 // @param maxChunkSize is in MBs. // -assertChunkSizes = function ( splitVec , numDocs , maxChunkSize ){ +assertChunkSizes = function ( splitVec , numDocs , maxChunkSize , msg ){ splitVec = [{ x: -1 }].concat( splitVec ); splitVec.push( { x: numDocs+1 } ); for ( i=0; i<splitVec.length-1; i++) { @@ -22,9 +22,9 @@ assertChunkSizes = function ( splitVec , numDocs , maxChunkSize ){ // It is okay for the last chunk to be smaller. A collection's size does not // need to be exactly a multiple of maxChunkSize. if ( i < splitVec.length - 2 ) - assert.close( maxChunkSize , size , "A"+i , -3 ); + assert.close( maxChunkSize , size , "A"+i , -3 ); else - assert.gt( maxChunkSize, size, "A"+i ); + assert.gt( maxChunkSize , size , "A"+i , msg + "b" ); } } @@ -37,27 +37,27 @@ f = db.jstests_splitvector; f.drop(); // ------------------------- -// Case: missing paramters +// Case 1: missing parameters -assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" } ).ok ); -assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" , maxChunkSize: 1} ).ok ); +assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" } ).ok , "1a" ); +assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" , maxChunkSize: 1} ).ok , "1b" ); // ------------------------- -// Case: missing index +// Case 2: missing index -assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ).ok ); +assert.eq( false, db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ).ok , "2"); // ------------------------- -// Case: empty collection +// Case 3: empty collection f.ensureIndex( { x: 1} ); -assert.eq( [], db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ).splitKeys ); +assert.eq( [], db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ).splitKeys , "3"); // ------------------------- -// Case: uniform collection +// Case 4: uniform collection f.drop(); f.ensureIndex( { x: 1 } ); @@ -67,15 +67,129 @@ filler = ""; while( filler.length < 500 ) filler += "a"; f.save( { x: 0, y: filler } ); docSize = db.runCommand( { datasize: "test.jstests_splitvector" } ).size; -assert.gt( docSize, 500 ); +assert.gt( docSize, 500 , "4a" ); // Fill collection and get split vector for 1MB maxChunkSize numDocs = 20000; for( i=1; i<numDocs; i++ ){ f.save( { x: i, y: filler } ); } +db.getLastError(); res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ); -assert.eq( true , res.ok ); -assert.close( numDocs*docSize / (1<<20) , res.splitKeys.length , "num split keys" , -1 ); -assertChunkSizes( res.splitKeys , numDocs, (1<<20) * 0.9 ); // splitVector cuts at 90% of maxChunkSize +// splitVector aims at getting half-full chunks after split +factor = 0.5; + +assert.eq( true , res.ok , "4b" ); +assert.close( numDocs*docSize / ((1<<20) * factor), res.splitKeys.length , "num split keys" , -1 ); +assertChunkSizes( res.splitKeys , numDocs, (1<<20) * factor , "4d" ); + + +// ------------------------- +// Case 5: limit number of split points + +f.drop(); +f.ensureIndex( { x: 1 } ); + +// Fill collection and get split vector for 1MB maxChunkSize +numDocs = 10000; +for( i=1; i<numDocs; i++ ){ + f.save( { x: i, y: filler } ); +} +db.getLastError(); +res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 , maxSplitPoints: 1} ); + +assert.eq( true , res.ok , "5a" ); +assert.eq( 1 , res.splitKeys.length , "5b" ); + + +// ------------------------- +// Case 6: limit number of objects in a chunk + +f.drop(); +f.ensureIndex( { x: 1 } ); + +// Fill collection and get split vector for 1MB maxChunkSize +numDocs = 10000; +for( i=1; i<numDocs; i++ ){ + f.save( { x: i, y: filler } ); +} +db.getLastError(); +res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 , maxChunkObjects: 500} ); + +assert.eq( true , res.ok , "6a" ); +assert.eq( 19 , res.splitKeys.length , "6b" ); + + +// ------------------------- +// Case 7: enough occurances of min key documents to pass the chunk limit +// [1111111111111111,2,3) + +f.drop(); +f.ensureIndex( { x: 1 } ); + +// Fill collection and get split vector for 1MB maxChunkSize +numDocs = 2100; +for( i=1; i<numDocs; i++ ){ + f.save( { x: 1, y: filler } ); +} + +for( i=1; i<10; i++ ){ + f.save( { x: 2, y: filler } ); +} +db.getLastError(); +res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ); + +assert.eq( true , res.ok , "7a" ); +assert.eq( 2 , res.splitKeys[0].x, "7b"); + + +// ------------------------- +// Case 8: few occurrances of min key, and enough of some other that we cannot split it +// [1, 22222222222222, 3) + +f.drop(); +f.ensureIndex( { x: 1 } ); + +for( i=1; i<10; i++ ){ + f.save( { x: 1, y: filler } ); +} + +numDocs = 2100; +for( i=1; i<numDocs; i++ ){ + f.save( { x: 2, y: filler } ); +} + +for( i=1; i<10; i++ ){ + f.save( { x: 3, y: filler } ); +} + +db.getLastError(); +res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , maxChunkSize: 1 } ); + +assert.eq( true , res.ok , "8a" ); +assert.eq( 2 , res.splitKeys.length , "8b" ); +assert.eq( 2 , res.splitKeys[0].x , "8c" ); +assert.eq( 3 , res.splitKeys[1].x , "8d" ); + + +// ------------------------- +// Case 9: splitVector "force" mode, where we split (possible small) chunks in the middle +// + +f.drop(); +f.ensureIndex( { x: 1 } ); + +f.save( { x: 1 } ); +f.save( { x: 2 } ); +f.save( { x: 3 } ); +db.getLastError(); + +res = db.runCommand( { splitVector: "test.jstests_splitvector" , keyPattern: {x:1} , force : true } ); + +assert.eq( true , res.ok , "9a" ); +assert.eq( 1 , res.splitKeys.length , "9b" ); +assert.eq( 2 , res.splitKeys[0].x , "9c" ); + + +print("PASSED"); |