nodes: 0, module; 1, function_definition; 2, function_name:repartitionAndSortWithinPartitions; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, expression_statement; 11, if_statement; 12, expression_statement; 13, expression_statement; 14, function_definition; 15, return_statement; 16, identifier:numPartitions; 17, None; 18, identifier:partitionFunc; 19, identifier:portable_hash; 20, identifier:ascending; 21, True; 22, identifier:keyfunc; 23, lambda; 24, comment:"""
          Repartition the RDD according to the given partitioner and, within each resulting partition,
          sort records by their keys.
  
          >>> rdd = sc.parallelize([(0, 5), (3, 8), (2, 6), (0, 8), (3, 8), (1, 3)])
          >>> rdd2 = rdd.repartitionAndSortWithinPartitions(2, lambda x: x % 2, True)
          >>> rdd2.glom().collect()
          [[(0, 5), (0, 8), (2, 6)], [(1, 3), (3, 8), (3, 8)]]
          """; 25, comparison_operator:numPartitions is None; 26, block; 27, assignment; 28, assignment; 29, function_name:sortPartition; 30, parameters; 31, block; 32, call; 33, lambda_parameters; 34, identifier:x; 35, identifier:numPartitions; 36, None; 37, expression_statement; 38, identifier:memory; 39, call; 40, identifier:serializer; 41, attribute; 42, identifier:iterator; 43, expression_statement; 44, return_statement; 45, attribute; 46, argument_list; 47, identifier:x; 48, assignment; 49, identifier:_parse_memory; 50, argument_list; 51, identifier:self; 52, identifier:_jrdd_deserializer; 53, assignment; 54, call; 55, call; 56, identifier:mapPartitions; 57, identifier:sortPartition; 58, True; 59, identifier:numPartitions; 60, call; 61, call; 62, identifier:sort; 63, attribute; 64, identifier:iter; 65, argument_list; 66, attribute; 67, argument_list; 68, attribute; 69, argument_list; 70, attribute; 71, argument_list; 72, call; 73, identifier:sorted; 74, call; 75, identifier:self; 76, identifier:partitionBy; 77, identifier:numPartitions; 78, identifier:partitionFunc; 79, identifier:self; 80, identifier:_defaultReducePartitions; 81, attribute; 82, identifier:get; 83, string:"spark.python.worker.memory"; 84, string:"512m"; 85, identifier:ExternalSorter; 86, argument_list; 87, identifier:sort; 88, argument_list; 89, attribute; 90, identifier:_conf; 91, binary_operator:memory * 0.9; 92, identifier:serializer; 93, identifier:iterator; 94, keyword_argument; 95, keyword_argument; 96, identifier:self; 97, identifier:ctx; 98, identifier:memory; 99, float:0.9; 100, identifier:key; 101, lambda; 102, identifier:reverse; 103, parenthesized_expression; 104, lambda_parameters; 105, call; 106, not_operator; 107, identifier:k_v; 108, identifier:keyfunc; 109, argument_list; 110, identifier:ascending; 111, subscript; 112, identifier:k_v; 113, integer:0
code: def repartitionAndSortWithinPartitions(self, numPartitions=None, partitionFunc=portable_hash,
                                             ascending=True, keyfunc=lambda x: x):
          """
          Repartition the RDD according to the given partitioner and, within each resulting partition,
          sort records by their keys.
  
          >>> rdd = sc.parallelize([(0, 5), (3, 8), (2, 6), (0, 8), (3, 8), (1, 3)])
          >>> rdd2 = rdd.repartitionAndSortWithinPartitions(2, lambda x: x % 2, True)
          >>> rdd2.glom().collect()
          [[(0, 5), (0, 8), (2, 6)], [(1, 3), (3, 8), (3, 8)]]
          """
          if numPartitions is None:
              numPartitions = self._defaultReducePartitions()
  
          memory = _parse_memory(self.ctx._conf.get("spark.python.worker.memory", "512m"))
          serializer = self._jrdd_deserializer
  
          def sortPartition(iterator):
              sort = ExternalSorter(memory * 0.9, serializer).sorted
              return iter(sort(iterator, key=lambda k_v: keyfunc(k_v[0]), reverse=(not ascending)))
  
          return self.partitionBy(numPartitions, partitionFunc).mapPartitions(sortPartition, True)