docstr: Searches the database for pairs of (hash, offset) values.
  
  :param hashes: A sequence of tuples in the format (hash, offset)
      - hash: Part of a sha1 hash, in hexadecimal format
      - offset: Offset this hash was created from/at.
  :param batch_size: number of query's batches.
  :return: a list of (sid, offset_difference) tuples and a
  dictionary with the amount of hashes matched (not considering
  duplicated hashes) in each song.
      - song id: Song identifier
      - offset_difference: (database_offset - sampled_offset)
docstr_tok: ["Searches","the","database","for","pairs","of","(","hash",",","offset",")","values",".",":","param","hashes",":","A","sequence","of","tuples","in","the","format","(","hash",",","offset",")","-","hash",":","Part","of","a","sha1","hash",",","in","hexadecimal","format","-","offset",":","Offset","this","hash","was","created","from\/at",".",":","param","batch_size",":","number","of","query","'s","batches",".",":","return",":","a","list","of","(","sid",",","offset_difference",")","tuples","and","a","dictionary","with","the","amount","of","hashes","matched","(","not","considering","duplicated","hashes",")","in","each","song",".","-","song","id",":","Song","identifier","-","offset_difference",":","(","database_offset","-","sampled_offset",")"]
code: def return_matches(
      self, hashes: List[Tuple[str, int]], batch_size: int = 1000
  ) -> Tuple[List[Tuple[int, int]], Dict[int, int]]:
      """
      Searches the database for pairs of (hash, offset) values.
  
      :param hashes: A sequence of tuples in the format (hash, offset)
          - hash: Part of a sha1 hash, in hexadecimal format
          - offset: Offset this hash was created from/at.
      :param batch_size: number of query's batches.
      :return: a list of (sid, offset_difference) tuples and a
      dictionary with the amount of hashes matched (not considering
      duplicated hashes) in each song.
          - song id: Song identifier
          - offset_difference: (database_offset - sampled_offset)
      """
      # Create a dictionary of hash => offset pairs for later lookups
      mapper = {}
      for hsh, offset in hashes:
          if hsh.upper() in mapper.keys():
              mapper[hsh.upper()].append(offset)
          else:
              mapper[hsh.upper()] = [offset]
  
      values = list(mapper.keys())
  
      # in order to count each hash only once per db offset we use the dic below
      dedup_hashes = {}
  
      results = []
      with self.cursor() as cur:
          for index in range(0, len(values), batch_size):
              # Create our IN part of the query
              query = self.SELECT_MULTIPLE % ", ".join(
                  [self.IN_MATCH]
                  * len(values[index : index + batch_size])
              )
  
              cur.execute(query, values[index : index + batch_size])
  
              for hsh, sid, offset in cur:
                  if sid not in dedup_hashes.keys():
                      dedup_hashes[sid] = 1
                  else:
                      dedup_hashes[sid] += 1
                  #  we now evaluate all offset for each  hash matched
                  for song_sampled_offset in mapper[hsh]:
                      results.append(
                          (sid, offset - song_sampled_offset)
                      )
  
          return results, dedup_hashes
  
imports: import abc
  from typing import Dict, List, Tuple
  from dejavu.base_classes.base_database import BaseDatabase
label_desc: Use image node_id 17 for calling the CommonDatabase obj's underlying member method code with example usage: obj.return_matches(hashes, batch_size) and returns: results,  dedup_hashes