sc_keyvalue_entry_type_t sc_keyvalue_unset (sc_keyvalue_t * kv, const char *key) { void *found; sc_keyvalue_entry_t svalue, *pvalue = &svalue; sc_keyvalue_entry_t *value; int remove_test; sc_keyvalue_entry_type_t type; SC_ASSERT (kv != NULL); SC_ASSERT (key != NULL); pvalue->key = key; pvalue->type = SC_KEYVALUE_ENTRY_NONE; /* Remove this entry */ remove_test = sc_hash_remove (kv->hash, pvalue, &found); /* Check whether anything was removed */ if (!remove_test) return SC_KEYVALUE_ENTRY_NONE; /* Code reaching this point must have found something */ SC_ASSERT (remove_test); SC_ASSERT (found != NULL); value = (sc_keyvalue_entry_t *) found; type = value->type; /* destroy the orignial hash entry */ sc_mempool_free (kv->value_allocator, value); return type; }
sc_keyvalue_t * sc_keyvalue_newv (va_list ap) { const char *s; int added; void **found; sc_keyvalue_t *kv; sc_keyvalue_entry_t *value; /* Create the initial empty keyvalue object */ kv = sc_keyvalue_new (); /* loop through the variable arguments to fill keyvalue */ for (;;) { s = va_arg (ap, const char *); if (s == NULL) { break; } /* if this assertion blows then the type prefix might be missing */ SC_ASSERT (s[0] != '\0' && s[1] == ':' && s[2] != '\0'); value = (sc_keyvalue_entry_t *) sc_mempool_alloc (kv->value_allocator); value->key = &s[2]; switch (s[0]) { case 'i': value->type = SC_KEYVALUE_ENTRY_INT; value->value.i = va_arg (ap, int); break; case 'g': value->type = SC_KEYVALUE_ENTRY_DOUBLE; value->value.g = va_arg (ap, double); break; case 's': value->type = SC_KEYVALUE_ENTRY_STRING; value->value.s = va_arg (ap, const char *); break; case 'p': value->type = SC_KEYVALUE_ENTRY_POINTER; value->value.p = va_arg (ap, void *); break; default: SC_ABORTF ("invalid argument character %c", s[0]); } added = sc_hash_insert_unique (kv->hash, value, &found); if (!added) { sc_mempool_free (kv->value_allocator, *found); *found = value; } } return kv; }
int main (int argc, char **argv) { sc_MPI_Comm mpicomm; int mpiret; int mpisize, mpirank; unsigned crc; #ifndef P4_TO_P8 size_t kz; int8_t l; p4est_quadrant_t *q; p4est_tree_t stree, *tree = &stree; #endif p4est_t *p4est; p4est_connectivity_t *connectivity; /* initialize MPI */ mpiret = sc_MPI_Init (&argc, &argv); SC_CHECK_MPI (mpiret); mpicomm = sc_MPI_COMM_WORLD; mpiret = sc_MPI_Comm_size (mpicomm, &mpisize); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Comm_rank (mpicomm, &mpirank); SC_CHECK_MPI (mpiret); sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT); p4est_init (NULL, SC_LP_DEFAULT); #ifndef P4_TO_P8 connectivity = p4est_connectivity_new_star (); #else connectivity = p8est_connectivity_new_rotcubes (); #endif p4est = p4est_new_ext (mpicomm, connectivity, 0, 0, 0, 4, NULL, NULL); #ifndef P4_TO_P8 /* build empty tree */ sc_array_init (&tree->quadrants, sizeof (p4est_quadrant_t)); for (l = 0; l <= P4EST_MAXLEVEL; ++l) { tree->quadrants_per_level[l] = 0; } tree->maxlevel = 0; /* insert two quadrants */ sc_array_resize (&tree->quadrants, 4); q = p4est_quadrant_array_index (&tree->quadrants, 0); p4est_quadrant_set_morton (q, 3, 13); q = p4est_quadrant_array_index (&tree->quadrants, 1); p4est_quadrant_set_morton (q, 1, 1); q = p4est_quadrant_array_index (&tree->quadrants, 2); p4est_quadrant_set_morton (q, 1, 2); q = p4est_quadrant_array_index (&tree->quadrants, 3); p4est_quadrant_set_morton (q, 1, 3); for (kz = 0; kz < tree->quadrants.elem_count; ++kz) { q = p4est_quadrant_array_index (&tree->quadrants, kz); q->p.user_data = sc_mempool_alloc (p4est->user_data_pool); ++tree->quadrants_per_level[q->level]; tree->maxlevel = (int8_t) SC_MAX (tree->maxlevel, q->level); } /* balance the tree, print and destroy */ #if 0 p4est_balance_subtree (p4est, P4EST_CONNECT_FULL, 0, NULL); p4est_tree_print (SC_LP_INFO, tree); #endif for (kz = 0; kz < tree->quadrants.elem_count; ++kz) { q = p4est_quadrant_array_index (&tree->quadrants, kz); sc_mempool_free (p4est->user_data_pool, q->p.user_data); } sc_array_reset (&tree->quadrants); #endif /* !P4_TO_P8 */ /* check reset data function */ p4est_reset_data (p4est, 0, init_fn, NULL); p4est_reset_data (p4est, 0, NULL, NULL); /* refine and balance the forest */ SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 1"); p4est_refine (p4est, 1, refine_fn, NULL); SC_CHECK_ABORT (!p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 2"); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 3"); /* check reset data function */ p4est_reset_data (p4est, 17, NULL, NULL); p4est_reset_data (p4est, 8, init_fn, NULL); /* checksum and partition */ crc = p4est_checksum (p4est); p4est_partition (p4est, 0, NULL); SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Partition"); SC_CHECK_ABORT (p4est_is_balanced (p4est, P4EST_CONNECT_FULL), "Balance 4"); /* check reset data function */ p4est_reset_data (p4est, 3, NULL, NULL); p4est_reset_data (p4est, 3, NULL, NULL); /* checksum and rebalance */ crc = p4est_checksum (p4est); p4est_balance (p4est, P4EST_CONNECT_FULL, NULL); SC_CHECK_ABORT (p4est_checksum (p4est) == crc, "Rebalance"); /* clean up and exit */ P4EST_ASSERT (p4est->user_data_pool->elem_count == (size_t) p4est->local_num_quadrants); p4est_destroy (p4est); p4est_connectivity_destroy (connectivity); sc_finalize (); mpiret = sc_MPI_Finalize (); SC_CHECK_MPI (mpiret); return 0; }