nodes: 0, module; 1, function_definition; 2, function_name:_gen_cache_key_for_slice; 3, parameters; 4, block; 5, identifier:url_dict; 6, identifier:start_int; 7, identifier:total_int; 8, identifier:authn_subj_list; 9, expression_statement; 10, comment:# logging.debug('Gen key. result_record_count={}'.format(result_record_count)); 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, return_statement; 17, comment:"""Generate cache key for the REST URL the client is currently accessing or is
      expected to access in order to get the slice starting at the given ``start_int`` of
      a multi-slice result set.
  
      When used for finding the key to check in the current call, ``start_int`` is
      0, or the start that was passed in the current call.
  
      When used for finding the key to set for the anticipated call, ``start_int`` is
      current ``start_int`` + ``count_int``, the number of objects the current call will
      return.
  
      The URL for the slice is the same as for the current slice, except that the
      `start` query parameter has been increased by the number of items returned in
      the current slice.
  
      Except for advancing the start value and potentially adjusting the desired
      slice size, it doesn't make sense for the client to change the REST URL during
      slicing, but such queries are supported. They will, however, trigger
      potentially expensive database queries to find the current slice position.
  
      To support adjustments in desired slice size during slicing, the count is not
      used when generating the key.
  
      The active subjects are used in the key in order to prevent potential security
      issues if authenticated subjects change during slicing.
  
      The url_dict is normalized by encoding it to a JSON string with sorted keys. A
      hash of the JSON is used for better distribution in a hash map and to avoid
      the 256 bytes limit on keys in some caches.
  
      """; 18, assignment; 19, call; 20, call; 21, assignment; 22, call; 23, call; 24, identifier:key_url_dict; 25, call; 26, attribute; 27, argument_list; 28, attribute; 29, argument_list; 30, identifier:key_json; 31, call; 32, attribute; 33, argument_list; 34, attribute; 35, argument_list; 36, attribute; 37, argument_list; 38, subscript; 39, identifier:pop; 40, string; 41, None; 42, subscript; 43, identifier:pop; 44, string; 45, None; 46, attribute; 47, argument_list; 48, identifier:logging; 49, identifier:debug; 50, call; 51, call; 52, identifier:hexdigest; 53, identifier:copy; 54, identifier:deepcopy; 55, identifier:url_dict; 56, identifier:key_url_dict; 57, string; 58, string_content:start; 59, identifier:key_url_dict; 60, string; 61, string_content:count; 62, attribute; 63, identifier:serialize_to_normalized_compact_json; 64, dictionary; 65, attribute; 66, argument_list; 67, attribute; 68, argument_list; 69, string_content:query; 70, string_content:query; 71, identifier:d1_common; 72, identifier:util; 73, pair; 74, pair; 75, pair; 76, pair; 77, string; 78, identifier:format; 79, identifier:key_json; 80, identifier:hashlib; 81, identifier:sha256; 82, call; 83, string; 84, identifier:key_url_dict; 85, string; 86, identifier:start_int; 87, string; 88, identifier:total_int; 89, string; 90, identifier:authn_subj_list; 91, string_content:key_json={}; 92, attribute; 93, argument_list; 94, string_content:url_dict; 95, string_content:start; 96, string_content:total; 97, string_content:subject; 98, identifier:key_json; 99, identifier:encode; 100, string; 101, string_content:utf-8
code: def _gen_cache_key_for_slice(url_dict, start_int, total_int, authn_subj_list):
      """Generate cache key for the REST URL the client is currently accessing or is
      expected to access in order to get the slice starting at the given ``start_int`` of
      a multi-slice result set.
  
      When used for finding the key to check in the current call, ``start_int`` is
      0, or the start that was passed in the current call.
  
      When used for finding the key to set for the anticipated call, ``start_int`` is
      current ``start_int`` + ``count_int``, the number of objects the current call will
      return.
  
      The URL for the slice is the same as for the current slice, except that the
      `start` query parameter has been increased by the number of items returned in
      the current slice.
  
      Except for advancing the start value and potentially adjusting the desired
      slice size, it doesn't make sense for the client to change the REST URL during
      slicing, but such queries are supported. They will, however, trigger
      potentially expensive database queries to find the current slice position.
  
      To support adjustments in desired slice size during slicing, the count is not
      used when generating the key.
  
      The active subjects are used in the key in order to prevent potential security
      issues if authenticated subjects change during slicing.
  
      The url_dict is normalized by encoding it to a JSON string with sorted keys. A
      hash of the JSON is used for better distribution in a hash map and to avoid
      the 256 bytes limit on keys in some caches.
  
      """
      # logging.debug('Gen key. result_record_count={}'.format(result_record_count))
      key_url_dict = copy.deepcopy(url_dict)
      key_url_dict['query'].pop('start', None)
      key_url_dict['query'].pop('count', None)
      key_json = d1_common.util.serialize_to_normalized_compact_json(
          {
              'url_dict': key_url_dict,
              'start': start_int,
              'total': total_int,
              'subject': authn_subj_list,
          }
      )
      logging.debug('key_json={}'.format(key_json))
      return hashlib.sha256(key_json.encode('utf-8')).hexdigest()