CZMQ Manual - CZMQ/2.2.1


zhash - generic type-free hash container


//  Callback function for zhash_foreach method
typedef int (zhash_foreach_fn) (const char *key, void *item, void *argument);
//  Callback function for zhash_freefn method
typedef void (zhash_free_fn) (void *data);

//  Create a new, empty hash container
CZMQ_EXPORT zhash_t *
    zhash_new (void);

//  Destroy a hash container and all items in it
    zhash_destroy (zhash_t **self_p);

//  Insert item into hash table with specified key and item.
//  If key is already present returns -1 and leaves existing item unchanged
//  Returns 0 on success.
    zhash_insert (zhash_t *self, const char *key, void *item);

//  Update item into hash table with specified key and item.
//  If key is already present, destroys old item and inserts new one.
//  Use free_fn method to ensure deallocator is properly called on item.
    zhash_update (zhash_t *self, const char *key, void *item);

//  Remove an item specified by key from the hash table. If there was no such
//  item, this function does nothing.
    zhash_delete (zhash_t *self, const char *key);

//  Return the item at the specified key, or null
    zhash_lookup (zhash_t *self, const char *key);

//  Reindexes an item from an old key to a new key. If there was no such
//  item, does nothing. Returns 0 if successful, else -1.
    zhash_rename (zhash_t *self, const char *old_key, const char *new_key);

//  Set a free function for the specified hash table item. When the item is
//  destroyed, the free function, if any, is called on that item.
//  Use this when hash items are dynamically allocated, to ensure that
//  you don't have memory leaks. You can pass 'free' or NULL as a free_fn.
//  Returns the item, or NULL if there is no such item.
    zhash_freefn (zhash_t *self, const char *key, zhash_free_fn *free_fn);

//  Return the number of keys/items in the hash table
    zhash_size (zhash_t *self);

//  Make copy of hash table
CZMQ_EXPORT zhash_t *
    zhash_dup (zhash_t *self);

//  Return keys for items in table
CZMQ_EXPORT zlist_t *
    zhash_keys (zhash_t *self);

//  Apply function to each item in the hash table. Items are iterated in no
//  defined order. Stops if callback function returns non-zero and returns
//  final return code from callback function (zero = success).
    zhash_foreach (zhash_t *self, zhash_foreach_fn *callback, void *argument);

//  Add comment to hash table before saving to disk. You can add as many
//  comment lines as you like. These comment lines are discarded when loading
//  the file. If you use a null format, all comments are deleted.
    zhash_comment (zhash_t *self, const char *format, ...);

//  Save hash table to a text file in name=value format. Hash values must be
//  printable strings; keys may not contain '=' character. Returns 0 if OK,
//  else -1 if a file error occurred.
    zhash_save (zhash_t *self, const char *filename);

//  Load hash table from a text file in name=value format; hash table must
//  already exist. Hash values must printable strings; keys may not contain
//  '=' character. Returns 0 if OK, else -1 if a file was not readable.
    zhash_load (zhash_t *self, const char *filename);

//  When a hash table was loaded from a file by zhash_load, this method will
//  reload the file if it has been modified since, and is "stable", i.e. not
//  still changing. Returns 0 if OK, -1 if there was an error reloading the
//  file.
    zhash_refresh (zhash_t *self);

//  Set hash for automatic value destruction
    zhash_autofree (zhash_t *self);

//  Serialize hash table to a binary frame that can be sent in a message.
//  The packed format is compatible with the 'dictionary' type defined in
//  http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto:
//     ; A list of name/value pairs
//     dictionary      = dict-count *( dict-name dict-value )
//     dict-count      = number-4
//     dict-value      = longstr
//     dict-name       = string
//     ; Strings are always length + text contents
//     longstr         = number-4 *VCHAR
//     string          = number-1 *VCHAR
//     ; Numbers are unsigned integers in network byte order
//     number-1        = 1OCTET
//     number-4        = 4OCTET
//  Comments are not included in the packed data. Item values MUST be
//  strings.
CZMQ_EXPORT zframe_t *
    zhash_pack (zhash_t *self);

//  Unpack binary frame into a new hash table. Packed data must follow format
//  defined by zhash_pack. Hash table is set to autofree. An empty frame
//  unpacks to an empty hash table.
CZMQ_EXPORT zhash_t *
    zhash_unpack (zframe_t *frame);

//  Self test of this class
    zhash_test (int verbose);


Expandable hash table container

Note that it's relatively slow (<subscript>50k insertions/deletes per second), so don't do inserts/updates on the critical path for message I/O. It can do </subscript>2.5M lookups per second for 16-char keys. Timed on a 1.6GHz CPU.


From zhash_test method

 zhash_t *hash = zhash_new ();
 assert (hash);
 assert (zhash_size (hash) == 0);

 // Insert some items
 int rc;
 rc = zhash_insert (hash, "DEADBEEF", "dead beef");
 assert (rc == 0);
 rc = zhash_insert (hash, "ABADCAFE", "a bad cafe");
 assert (rc == 0);
 rc = zhash_insert (hash, "C0DEDBAD", "coded bad");
 assert (rc == 0);
 rc = zhash_insert (hash, "DEADF00D", "dead food");
 assert (rc == 0);
 assert (zhash_size (hash) == 4);

 // Look for existing items
 char *item;
 item = (char *) zhash_lookup (hash, "DEADBEEF");
 assert (streq (item, "dead beef"));
 item = (char *) zhash_lookup (hash, "ABADCAFE");
 assert (streq (item, "a bad cafe"));
 item = (char *) zhash_lookup (hash, "C0DEDBAD");
 assert (streq (item, "coded bad"));
 item = (char *) zhash_lookup (hash, "DEADF00D");
 assert (streq (item, "dead food"));

 // Look for non-existent items
 item = (char *) zhash_lookup (hash, "foo");
 assert (item == NULL);

 // Try to insert duplicate items
 rc = zhash_insert (hash, "DEADBEEF", "foo");
 assert (rc == -1);
 item = (char *) zhash_lookup (hash, "DEADBEEF");
 assert (streq (item, "dead beef"));

 // Some rename tests

 // Valid rename, key is now LIVEBEEF
 rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF");
 assert (rc == 0);
 item = (char *) zhash_lookup (hash, "LIVEBEEF");
 assert (streq (item, "dead beef"));

 // Trying to rename an unknown item to a non-existent key
 rc = zhash_rename (hash, "WHATBEEF", "NONESUCH");
 assert (rc == -1);

 // Trying to rename an unknown item to an existing key
 rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF");
 assert (rc == -1);
 item = (char *) zhash_lookup (hash, "LIVEBEEF");
 assert (streq (item, "dead beef"));

 // Trying to rename an existing item to another existing item
 rc = zhash_rename (hash, "LIVEBEEF", "ABADCAFE");
 assert (rc == -1);
 item = (char *) zhash_lookup (hash, "LIVEBEEF");
 assert (streq (item, "dead beef"));
 item = (char *) zhash_lookup (hash, "ABADCAFE");
 assert (streq (item, "a bad cafe"));

 // Test keys method
 zlist_t *keys = zhash_keys (hash);
 assert (zlist_size (keys) == 4);
 zlist_destroy (&keys);

 // Test dup method
 zhash_t *copy = zhash_dup (hash);
 assert (zhash_size (copy) == 4);
 item = (char *) zhash_lookup (copy, "LIVEBEEF");
 assert (item);
 assert (streq (item, "dead beef"));
 zhash_destroy (&copy);

 // Test pack/unpack methods
 zframe_t *frame = zhash_pack (hash);
 copy = zhash_unpack (frame);
 zframe_destroy (&frame);
 assert (zhash_size (copy) == 4);
 item = (char *) zhash_lookup (copy, "LIVEBEEF");
 assert (item);
 assert (streq (item, "dead beef"));
 zhash_destroy (&copy);

 // Test foreach
 assert (0 == zhash_foreach (hash, test_foreach, hash));
 assert (-1 == zhash_foreach (hash, test_foreach_error, hash));

 // Test save and load
 zhash_comment (hash, "This is a test file");
 zhash_comment (hash, "Created by %s", "czmq_selftest");
 zhash_save (hash, ".cache");
 copy = zhash_new ();
 zhash_load (copy, ".cache");
 item = (char *) zhash_lookup (copy, "LIVEBEEF");
 assert (item);
 assert (streq (item, "dead beef"));
 zhash_destroy (&copy);
 zsys_file_delete (".cache");

 // Delete a item
 zhash_delete (hash, "LIVEBEEF");
 item = (char *) zhash_lookup (hash, "LIVEBEEF");
 assert (item == NULL);
 assert (zhash_size (hash) == 3);

 // Check that the queue is robust against random usage
 struct {
 char name [100];
 bool exists;
 } testset [200];
 memset (testset, 0, sizeof (testset));
 int testmax = 200, testnbr, iteration;

 srandom ((unsigned) time (NULL));
 for (iteration = 0; iteration < 25000; iteration++) {
 testnbr = randof (testmax);
 if (testset [testnbr].exists) {
 item = (char *) zhash_lookup (hash, testset [testnbr].name);
 assert (item);
 zhash_delete (hash, testset [testnbr].name);
 testset [testnbr].exists = false;
 else {
 sprintf (testset [testnbr].name, "%x-%x", rand (), rand ());
 if (zhash_insert (hash, testset [testnbr].name, "") == 0)
 testset [testnbr].exists = true;
 // Test 10K lookups
 for (iteration = 0; iteration < 10000; iteration++)
 item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE");

 // Destructor should be safe to call twice
 zhash_destroy (&hash);
 zhash_destroy (&hash);
 assert (hash == NULL);

 // Test autofree; automatically copies and frees string values
 hash = zhash_new ();
 zhash_autofree (hash);
 char value [255];
 strcpy (value, "This is a string");
 rc = zhash_insert (hash, "key1", value);
 assert (rc == 0);
 strcpy (value, "Ring a ding ding");
 rc = zhash_insert (hash, "key2", value);
 assert (rc == 0);
 assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string"));
 assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding"));  zhash_destroy (&hash);

See also



The CZMQ manual was written by Pieter Hintjens<moc.xitami|hp#moc.xitami|hp>.


Main web site: http://czmq.zeromq.org/

Report bugs to the ØMQ development mailing list: <gro.qmorez.stsil|ved-qmorez#gro.qmorez.stsil|ved-qmorez>


Copyright (c) 1991-2014 iMatix and Contributors. License LGPLv3+: GNU LGPL 3 or later <http://gnu.org/licenses/lgpl.html>. This is free software: you are free to change it and redistribute it. There is NO WARRANTY, to the extent permitted by law. For details see the files COPYING and COPYING.LESSER included with the CZMQ distribution.