# 2.4.2.4 Modification

typedef bool (*ZixKeyMatchFunc)(const ZixHashKey *key, const ZixHashSearchData *user_data)

  User function for determining if a key matches in a custom search.

struct ZixHashInsertPlan

  A “plan” (position) to insert a record in a hash table.

  This contains everything necessary to insert a record, except the record itself. It is exposed to split up insertion so that records only need to be allocated if an existing record is not found, but the contents should be considered opaque to the user.

  ZixHashCode code

    Hash code used to find this position.

  ZixHashIter index

    Index into hash table.

ZixStatus zix_hash_erase(ZixHash *hash, ZixHashIter i, ZixHashRecord **removed)

  Erase a record at a specific position.

  Parameters:

    - hash – The hash table to remove the record from.

    - i – Iterator to the record to remove. This must be a valid iterator from an earlier call to `zix_hash_find()`, that is, the hash table must not have been modified since.

    - removed – Set to the removed record, or null.

  Returns:

    ZIX_STATUS_SUCCES or ZIX_STATUS_BAD_ARG if `i` does not point at a removable record.

ZixStatus zix_hash_insert(ZixHash *hash, ZixHashRecord *record)

  Insert a record.

  This is a trivial wrapper for `zix_hash_plan_insert()` and `zix_hash_insert_at()` that is more convenient when record construction is not expensive.

  Parameters:

    - hash – The hash table.

    - record – The record to insert which, on success, can now be considered owned by the hash table.

  Returns:

    ZIX_STATUS_SUCCESS, ZIX_STATUS_EXISTS, or ZIX_STATUS_NO_MEM.

ZixStatus zix_hash_insert_at(ZixHash *hash, ZixHashInsertPlan position, ZixHashRecord *record)

  Insert a record at a specific position.

  The position must have been found with an earlier call to `zix_hash_plan_insert()`, and no modifications must have been made to the hash table since.

  Parameters:

    - hash – The hash table.

    - position – The position for the new record.

    - record – The record to insert which, on success, can now be considered owned by the hash table.

  Returns:

    ZIX_STATUS_SUCCESS, ZIX_STATUS_EXISTS if a record already exists at this position, or ZIX_STATUS_NO_MEM if growing the hash table failed.

ZixHashInsertPlan zix_hash_plan_insert(const ZixHash *hash, const ZixHashKey *key)

  Find the best position to insert a record with the given key.

  This searches the hash table and returns either the position of an existing equivalent record, or the best available position to insert a new one. The difference can be determined with `zix_hash_record_at()`.

  If the returned position is not occupied, then it is valid to insert a record with this key using `zix_hash_insert_at()` until the hash table is modified (which invalidates the position).

ZixHashInsertPlan zix_hash_plan_insert_prehashed(const ZixHash *hash, ZixHashCode code, ZixKeyMatchFunc predicate, const ZixHashSearchData *user_data)

  Find the best position to insert a record with a custom search.

  This is an advanced low-level version of `zix_hash_plan_insert()`. It allows a precalculated hash code to be given, along with a custom search predicate. These must be compatible with the functions that manage the hash table: trivial usage would be to pass the equality function used by the hash and the key to search for.

  This is exposed to make it possible to avoid constructing a key at all when potentially inserting. For example, if keys are structures with a fixed header and a variably-sized body, and you have a separate header and body this can be used to find an insert position without having to allocate a contiguous key.

  Note that care must be taken when using this function: improper use can corrupt the hash table. The hash code given must be correct for the key to be inserted, and the predicate must return true only if the key it is called with (the first argument) matches the key to be inserted.

ZixHashRecord *zix_hash_record_at(const ZixHash *hash, ZixHashInsertPlan position)

  Return the record at the given position, or null.

  This is used to determine if a position returned from `zix_hash_plan_insert()` can be used to insert a new record, or to access the existing matching record.

ZixStatus zix_hash_remove(ZixHash *hash, const ZixHashKey *key, ZixHashRecord **removed)

  Remove a record.

  Parameters:

    - hash – The hash table.

    - key – The key of the record to remove.

    - removed – Set to the removed record, or null.

  Returns:

    ZIX_STATUS_SUCCES or ZIX_STATUS_NOT_FOUND.