text: 'use strict';
  
  /*
   * yield_and_sorted.js (extends yield_rooted_or.js)
   *
   * Intersperse queries which use the AND_SORTED stage with updates and deletes of documents they
   * may match.
   */
  load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkload
  load('jstests/concurrency/fsm_workloads/yield_rooted_or.js'); // for $config
  
  var $config = extendWorkload($config, function($config, $super) {
  
      /*
       * Issue a query that will use the AND_SORTED stage. This is a little tricky, so use
       * stagedebug to force it to happen. Unfortunately this means it can't be batched.
       */
      $config.states.query = function andSorted(db, collName) {
          // Not very many docs returned in this, so loop to increase chances of yielding in the
          // middle.
          for (var i = 0; i < 100; i++) {
              // Construct the query plan: two ixscans under an andSorted.
              // Scan a == 0
              var ixscan1 = { ixscan: { args: { name: 'stages_and_sorted', keyPattern: { c: 1 },
                                                startKey: { '': 0 }, endKey: { '': 0 },
                                                endKeyInclusive: false, direction: 1 } } };
              // Scan b == this.nDocs
              var ixscan2 = { ixscan: { args: { name: 'stages_and_sorted', keyPattern: { d: 1 },
                                                startKey: { '': this.nDocs },
                                                endKey: { '': this.nDocs },
                                                endKeyInclusive: false, direction: -1 } } };
  
              // Intersect the two
              var andix1ix2 = { andSorted: { args: { nodes: [ixscan1, ixscan2] } } };
              var res = db.runCommand({ stageDebug: { collection: collName, plan: andix1ix2 } });
              assertAlways.commandWorked(res);
              for (var j = 0; j < res.results.length; j++) {
                  var result = res.results[j];
                  // These should always be true, since they're just verifying that the results match
                  // the query predicate.
                  assertAlways.eq(result.c, 0);
                  assertAlways.eq(result.d, this.nDocs);
              }
          }
      };
  
      return $config;
  });
  