Skip to content

San7o/hashmap.h

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hashmap.h
=========

Header-only implementation of an hashmap in C99 for any type.

Author:  Giovanni Santini
Mail:    [email protected]
License: MIT


Documentation
-------------

This is an hashmap implementation with linked list buckets. Values
are deep copied when added to the map using a function specified by
the user, and are freed when removed / destroyed with another user
function. This implementation is based on the symbol hashmap in
https://github.com/San7o/haplolang.

Api:

   HASHMAP_DECLARE(prefix, hash_fn, key_type, value_type,
                   value_deep_copy_fn, value_free_fn)
     Declare an hashmap for value_type
     Args:
       - prefix: define a prefix for the hashmap functions and types.
       - hash_fn: an hash function. Must have the signature:

            hashmap_hash_t hash_fn(key_type key, unsigned int key_len);

       - key_type: type of the key (that will get hashed)
       - value_type: type of the value held in the hashmap
       - value_deep_copy_fn: function to deep copy a value. Must
         have the signature:

            value_type value_deep_copy_fn(value_type *val);

       - value_free_fn: free a value. Must have the signature:

            void value_free_fn(value_type *val);

   hashmap_hash_t
      Type of an hash. An hash function is expected to return this,
      or a type error will be generated by the compiler.

   prefix_map_list
      Hashmap bucket type

   prefix_map
      The hashmap type

   int prefix_map_init(prefix_map *map, int capacity);
       Initialize a [map] with [capacity]
       Returns: 0 on success, or a negative HASHMAP_ERROR_ on error.
       Note: You should destroy it when you are done.

    int prefix_map_destroy(prefix_map *map);
       Destroy a previously initialized [map]
       Returns: 0 on success, or a negative HASHMAP_ERROR_ on failure.

    prefix_map* prefix_map_deep_copy(prefix_map *map);
       Create a new deep copy of [map]
       Returns: a deep copy of [map]
       Note: Remember to also destroy the copy when you are done.

    value_type*
    prefix_map_lookup(prefix_map *map,
                      key_type key,
                      unsigned int key_len);
       Lookup a [key] of [key_len] length in [map]
       Returns: a pointer to the value if present, or NULL otherwise.

    int prefix_map_update(prefix_map *map,
                          key_type key,
                          unsigned int key_len,
                          value_type *value);
       Insert / Update [value] with [key] of [ley_len] length in
       [map]
       Returns a positive value on success, which is either 0 if a
       new value was added or 1 if an existing value was modified,
       or a negative HASHMAP_ERROR_ in case of an error.

    int prefix_map_delete(prefix_map *map,
                          key_type key,
                          unsigned int key_len)

       Delete an entry with [key] of [key_len] length in [map]
       Returns 0 on success, or a negative HASHMAP_ERROR_ on error.

    hashmap_hash_t hashmap_hash_char(char *bytes, unsigned int len);
    hashmap_hash_t hashmap_hash_int32(uint32_t a, unsigned int ignored);
      Some sample hash functions, so you don't have to re-implement
      them yourself. Check out micro-hash.h (github@San7o) for more
      hashes.

Non user facing apis:

    prefix_map_list_free(prefix_map_list *list)
    prefix_map_list* prefix_map_list_deep_copy(prefix_map_list *list)


Usage
-----

Just #include "hashmap.h".

If you want to use the built-in hash functions, you need to also

   #define HASHMAP_IMPLEMENTATION

before including the header.

You can tune the library by #defining the allocator and free
functions. See the "Config" comments under "Configuration" section in
the header.

To start using an hashmap, you first need to declare one with the
macro HASHMAP_DECLARE. For example:

   HASHMAP_DECLARE(example, hashmap_hash_char, char*,
                   ExampleType, example_deep_copy, example_free)

Now you can start using the functions prefixed with "example".

    example_map map;
    example_map_init(&map, 1024);  // initialize

    ExampleType example_value = {
       .a = 10,
       .b = "it just works",
    };
    example_map_update(&map, "example", strlen("example"), &example_value);

    ExampleType *value = example_map_lookup(&map, "example", 8);
    assert(value != NULL);
    assert(value->a == 10);
    assert(value->b == example.b);
 
    example_map_destroy(&map);     // destroy

See full example at the end of the header.

Code
----

The official git repository of hashmap.h is hosted at:

    https://github.com/San7o/hashmap.h

This is part of a bigger collection of header-only C99 libraries
called "micro-headers", contributions are welcome:

    https://github.com/San7o/micro-headers

About

Header-only implementation of an hashmap in C99 for any type.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published