<commit_before><?
function Multi_Hash(array $t_args, array $inputs, array $outputs)
{
    // Class name randomly generated
    $className = generate_name('Hash');

    // Processing of template arguments.
    $split = $t_args['split'];

    // Processing of inputs.
    $keys = array_slice($inputs, 0, $split);
    $vals = array_slice($inputs, $split);

    $sys_headers  = ['tuple', 'unordered_map'];
    $user_headers = [];
    $lib_headers  = ['HashFct.h'];
    $libraries    = [];
    $properties   = [];
    $extra        = ['keys' => $keys, 'vals' => $vals];
    $result_type  = ['state'];
?>

class <?=$className?>;

class <?=$className?> {
 public:
  // The standard hashing for Grokit is used, which returns a uint64_t.
  using Key = uint64_t;

  // The value type for the map that contains the various values passed through.
  using Tuple = std::tuple<<?=typed($vals)?>>;

  // The map used, which must be a multimap.
  using Map = std::unordered_multimap<uint64_t, Tuple>;

 private:
  // The container that gathers the input.
  Map map;

 public:
  <?=$className?>() {}

  void AddItem(<?=const_typed_ref_args($inputs)?>) {
    auto key = ChainHash(<?=args($keys)?>);
    auto val = std::make_tuple(<?=args($vals)?>);
    map.insert(std::make_pair(key, val));
  }

  void AddState(<?=$className?>& other) {
    map.insert(other.map.begin(), other.map.end());
  }

  const Map& GetMap() const {
    return map;
  }

  static uint64_t ChainHash(<?=const_typed_ref_args($keys)?>) {
    uint64_t offset = 1;
<?  foreach (array_keys($keys) as $name) { ?>
    offset = CongruentHash(Hash(<?=$name?>), offset);
<?  } ?>
    return offset;
  }
};

<?
    return [
        'kind'           => 'GLA',
        'name'           => $className,
        'system_headers' => $sys_headers,
        'user_headers'   => $user_headers,
        'lib_headers'    => $lib_headers,
        'libraries'      => $libraries,
        'properties'     => $properties,
        'extra'          => $extra,
        'iterable'       => false,<commit_msg>Changed key creation to allow for reverse lookup<commit_after><?
function Multi_Hash(array $t_args, array $inputs, array $outputs)
{
    // Class name randomly generated
    $className = generate_name('Hash');

    // Processing of template arguments.
    $split = $t_args['split'];
    $seed = get_default($t_args, 'seed', 0);

    // Processing of inputs.
    $keys = array_slice($inputs, 0, $split);
    $vals = array_slice($inputs, $split);

    // Local names for the inputs are generated.
    foreach (array_values($keys) as $index => $type)
        $inputs_["key$index"] = $type;
    foreach (array_values($keys) as $index => $type)
        $inputs_["val$index"] = $type;

    // Re-assigned using local names for the inputs.
    $keys = array_slice($inputs_, 0, $split);
    $vals = array_slice($inputs_, $split);

    $sys_headers  = ['tuple', 'unordered_map'];
    $user_headers = [];
    $lib_headers  = ['HashFct.h'];
    $libraries    = [];
    $properties   = [];
    $extra        = ['keys' => $keys, 'vals' => $vals];
    $result_type  = ['state'];
?>

class <?=$className?>;

class <?=$className?> {
 public:
  // The seed for the chain hash.
  static const constexpr size_t kSeed = <?=$seed?>;

  // The value type for the map that contains the various values passed through.
  using Tuple = std::tuple<<?=typed($vals)?>>;

  // The keys are placed into one overall key.
  struct Key {
    // The various hashing attributes.
    <?=array_template('{val} {key};', PHP_EOL . '    ', $keys)?>

    // Simple initializer list to copy inner keys.
    Key(<?=const_typed_ref_args($keys)?>)
      : <?=array_template('{key}({key})', ',' . PHP_EOL . '        ', $keys)?> {
    }

    bool operator==(const Key& other) const {
      return <?=array_template('{key} == other.{key}',' && ', $keys)?>;
    }

    bool operator<(const Key& other) const {
<?  foreach ($keys as $name => $type) { ?>
  if (<?=$name?> < other.<?=$name?>)
        return true;
          if (!(<?=$name?> < other.<?=$name?>))
        return false;
<?  } ?>
      return false;
    }

    // The chain-hash across the inner keys.
    size_t ChainHash() const {
      uint64_t hash = kSeed;
      <?=array_template('hash = SpookyHash(Hash({key}), hash);',
                        PHP_EOL . '      ', $keys)?>
      return hash;
    }

    // Getter methods for each inner key.
<?  foreach (array_keys($keys) as $index => $key) { ?>
    const <?=$keys[$key]?>& GetKey<?=$index?>() const {
      return <?=$key?>;
    }
<?  } ?>
  };

  // The structure used to template the map.
  struct HashKey {
    size_t operator()(const Key& key) const {
      return key.ChainHash();
    }
  };

  // The map used, which must be a multimap.
  using Map = mct::closed_hash_map<Key, Tuple, HashKey>;

 private:
  // The container that gathers the input.
  Map map;

 public:
  <?=$className?>() {}

  void AddItem(<?=const_typed_ref_args($inputs_)?>) {
    auto key = Key(<?=args($keys)?>);
    auto val = std::make_tuple(<?=args($vals)?>);
    map.insert(std::make_pair(key, val));
  }

  void AddState(<?=$className?>& other) {
    map.insert(other.map.begin(), other.map.end());
  }

  const Map& GetMap() const {
    return map;
  }
};

<?
    return [
        'kind'           => 'GLA',
        'name'           => $className,
        'system_headers' => $sys_headers,
        'user_headers'   => $user_headers,
        'lib_headers'    => $lib_headers,
        'libraries'      => $libraries,
        'properties'     => $properties,
        'extra'          => $extra,
        'iterable'       => false,
{'fraction_non_alphanumeric': 0.17946890037426483, 'fraction_numerical': 0.0030297629656032793, 'mean_word_length': 2.706737120211361, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '483206', 'n_tokens_mistral': 1879, 'n_tokens_neox': 1830, 'n_words': 457}