Sorry, I missed this message a couple of days ago. Answers inline...

From: Vishal1 Sharma
Sent: 11 March 2020 12:37
To: 'vpp-dev@lists.fd.io' <vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>>
Subject: Storing a struct as a value in BiHash

Hello all,
I’m new to using vpp-infra and I’m currently trying to use hash table in order 
to store some structs as value. Thanks to Dave Barach, I’ve got a sample 
program for inserting a value and fetching that. However, I have some queries 
regarding the program. Given below is the program:

#include <stdio.h>
#include "vppinfra/bihash_8_8.h"
#include "vppinfra/bihash_template.c"

//This is my structure that I want to save as value.
typedef struct
{
  int a;
  char b[100];
  char c;
} design_t;

typedef struct
{
  /* Pool of designs */
  design_t *designs;
  /* design by key */
  uword *design_by_key;
} test_main_t;

test_main_t test_main;

int main (int argc, char **argv)
{
  test_main_t *tm = &test_main;
  design_t *elt;
  uword *p;

  /* Initialize the memory allocator */
  clib_mem_init (0, 128<<20);

  /* Create a 32-bit key hash table with a 32-bit value */
  tm->design_by_key = hash_create (0, sizeof (32));

  /*
   * Create an element
   * Remember that pools are vectors, which can/will MOVE
   * when resized. Always memorize pool indices, NOT pointers.
   */
  pool_get (tm->designs, elt);
  memset (elt, 0, sizeof (*elt)); /* pool_get doesn't zero memory */

  elt->a = 42;
  strncpy (elt->b, "Vishal Sharma", sizeof (elt->b));
  elt->c = 'v';

  /* Add the pool element INDEX to the hash table */
  hash_set (tm->design_by_key, 42, elt - tm->designs);

  /* For fun, look up the design_t we put into the hash table */

  p = hash_get (tm->design_by_key, 42);
  ASSERT (p);

  elt = pool_elt_at_index (tm->designs, p[0]);
  ASSERT (elt->a == 42);
  exit (0);
}

I’m compiling this above program by: gcc -o exe prog.c -lvppinfra -I ../ -ggdb3 
-I ./vpp/build-root/build-vpp_debug-native/vpp/
Given below are my queries:

  1.  I didn’t understand the purpose of “test_main_t”. Why is it required?

If you look at vlib/vnet/plugins, you’ll see this coding pattern all over the 
place. Typically, one ends up with faster object code as a result. It’s not 
“required,” but it is pretty effective.


  1.  By calling clib_mem_init(), some memory allocation is happening. What 
will happen if my usage exceeds that? Will it automatically resize?

Clib_mem_init(0, <size>) allocates <size> worth of virtual space, and sets the 
heap so that it will expand as needed. If you pass a chunk of memory (e.g. 
acquired by calling mmap) the heap will be fixed-size.


  1.  By looking at “pool_get (tm->designs, elt);” it seems that we’re getting 
some memory for ‘elt’ from ‘tm->designs’ which was described as ‘pool of 
desgins’. But when did we allocate the memory for this ‘pool of designs’? Do I 
have to call ‘pool_get()’ every time when I have to insert a key-value pair in 
the hash table?

Take a look at .../src/vppinfra/pool.h. Pools are dynamic arrays (vectors) with 
headers. The header has a free-element bitmap, and a freelist. All of the pool 
structures are dynamic, no need to manually allocate the pool. Fixed-size, 
preallocated pools are also supported; no need to go there in this case.

The only “gotcha” with pools: they ARE dynamic, so memorizing the address of a 
pool element is a bad mistake.

Call pool_get to acquire a new element from a pool. In most cases, the vector 
will not expand, so the operation is extremely fast.



  1.  When we are setting the key-value in the hash table by calling 
‘hash_set()’, I didn’t understand the 3rd argument being passed. Why is it ‘elt 
- tm->designs’ and not just ‘elt’? What’s being done by the subtraction here?

Always memorize pool indices. Never memorize a pointer to the ith element of a 
pool. Again, pools are dynamic. When a pool expands, we copy the current 
contents to a new, larger chunk of allocated memory. We free the old memory. 
Sticking pointers to pool elements into a hash table is a bad mistake, and 
leads to catastrophic failure when the old memory is reallocated.

I’ll be grateful if somebody can answer these queries.

Thanks and regards,
Vishal Sharma


"Confidentiality Warning: This message and any attachments are intended only 
for the use of the intended recipient(s), are confidential and may be 
privileged. If you are not the intended recipient, you are hereby notified that 
any review, re-transmission, conversion to hard copy, copying, circulation or 
other use of this message and any attachments is strictly prohibited. If you 
are not the intended recipient, please notify the sender immediately by return 
email and delete this message and any attachments from your system.

Virus Warning: Although the company has taken reasonable precautions to ensure 
no viruses are present in this email. The company cannot accept responsibility 
for any loss or damage arising from the use of this email or attachment."
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.

View/Reply Online (#15775): https://lists.fd.io/g/vpp-dev/message/15775
Mute This Topic: https://lists.fd.io/mt/71926775/21656
Group Owner: vpp-dev+ow...@lists.fd.io
Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to