Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
ZHASH(3)			  CZMQ Manual			      ZHASH(3)

NAME
       zhash - Class for simple	generic	hash container

SYNOPSIS
       //  This	is a stable class, and may not change except for emergencies. It
       //  is provided in stable builds.
       // 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);

       //  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);

       //  Destroy a hash container and	all items in it
       CZMQ_EXPORT void
	   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.
       CZMQ_EXPORT int
	   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.
       CZMQ_EXPORT void
	   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.
       CZMQ_EXPORT void
	   zhash_delete	(zhash_t *self,	const char *key);

       //  Return the item at the specified key, or null
       CZMQ_EXPORT void	*
	   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.
       CZMQ_EXPORT int
	   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.
       CZMQ_EXPORT void	*
	   zhash_freefn	(zhash_t *self,	const char *key, zhash_free_fn free_fn);

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

       //  Make	copy of	hash table; if supplied	table is null, returns null.
       //  Does	not copy items themselves. Rebuilds new	table so may be	slow on
       //  very	large tables. NOTE: only works with item values	that are strings
       //  since there's no other way to know how to duplicate the item	value.
       //  Caller owns return value and	must destroy it	when done.
       CZMQ_EXPORT zhash_t *
	   zhash_dup (zhash_t *self);

       //  Return keys for items in table
       //  Caller owns return value and	must destroy it	when done.
       CZMQ_EXPORT zlist_t *
	   zhash_keys (zhash_t *self);

       //  Simple iterator; returns first item in hash table, in no given order,
       //  or NULL if the table	is empty. This method is simpler to use	than the
       //  foreach() method, which is deprecated. To access the	key for	this item
       //  use zhash_cursor(). NOTE: do	NOT modify the table while iterating.
       CZMQ_EXPORT void	*
	   zhash_first (zhash_t	*self);

       //  Simple iterator; returns next item in hash table, in	no given order,
       //  or NULL if the last item was	already	returned. Use this together with
       //  zhash_first() to process all	items in a hash	table. If you need the
       //  items in sorted order, use zhash_keys() and then zlist_sort(). To
       //  access the key for this item	use zhash_cursor(). NOTE: do NOT modify
       //  the table while iterating.
       CZMQ_EXPORT void	*
	   zhash_next (zhash_t *self);

       //  After a successful first/next method, returns the key for the item that
       //  was returned. This is a constant string that	you may	not modify or
       //  deallocate, and which lasts as long as the item in the hash.	After an
       //  unsuccessful	first/next, returns NULL.
       CZMQ_EXPORT const char *
	   zhash_cursor	(zhash_t *self);

       //  Add a 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.
       CZMQ_EXPORT void
	   zhash_comment (zhash_t *self, const char *format, ...) CHECK_PRINTF (2);

       //  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.
       //  Caller owns return value and	must destroy it	when done.
       CZMQ_EXPORT zframe_t *
	   zhash_pack (zhash_t *self);

       //  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.
       CZMQ_EXPORT int
	   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.
       CZMQ_EXPORT int
	   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.
       CZMQ_EXPORT int
	   zhash_refresh (zhash_t *self);

       //  Set hash for	automatic value	destruction. Note that this assumes that
       //  values are NULL-terminated strings. Do not use with different types.
       CZMQ_EXPORT void
	   zhash_autofree (zhash_t *self);

       //  Self	test of	this class.
       CZMQ_EXPORT void
	   zhash_test (bool verbose);

       Please add '@interface' section in './../src/zhash.c'.

DESCRIPTION
       zhash is	an expandable hash table container. This is a simple
       container. For heavy-duty applications we recommend using zhashx.

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

EXAMPLE
       From zhash_test method.

	   zhash_t *hash = zhash_new ();
	   assert (hash);
	   assert (zhash_size (hash) ==	0);
	   assert (zhash_first (hash) == NULL);
	   assert (zhash_cursor	(hash) == NULL);

	   //  Insert some items
	   int rc;
	   rc =	zhash_insert (hash, "DEADBEEF",	"dead beef");
	   char	*item =	(char *) zhash_first (hash);
	   assert (streq (zhash_cursor (hash), "DEADBEEF"));
	   assert (streq (item,	"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
	   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 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 ();
	   assert (copy);
	   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);
	       assert (testnbr != testmax);
	       assert (testnbr < 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 ();
	   assert (hash);
	   zhash_autofree (hash);
	   char	value [255];
	   strcpy (value, "This	is a string");
	   rc =	zhash_insert (hash, "key1", value);
	   assert (rc == 0);
	   strcpy (value, "Inserting with the same key will fail");
	   rc =	zhash_insert (hash, "key1", value);
	   assert (rc == -1);
	   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);

	   #if defined (__WINDOWS__)
	   zsys_shutdown();
	   #endif

AUTHORS
       The czmq	manual was written by the authors in the AUTHORS file.

RESOURCES
       Main web	site:

       Report bugs to the email	<zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
       Copyright (c) the Contributors as noted in the AUTHORS file. This file
       is part of CZMQ,	the high-level C binding for 0MQ:
       http://czmq.zeromq.org. This Source Code	Form is	subject	to the terms
       of the Mozilla Public License, v. 2.0. If a copy	of the MPL was not
       distributed with	this file, You can obtain one at
       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
       distribution.

NOTES
	1. zeromq-dev@lists.zeromq.org
	   mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.2.1			  11/01/2025			      ZHASH(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zhash&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help