示例#1
0
// **TODO**: Add an test. This function shows only the usage of `append_cb`.
static char * test_single() {

	mpz_t a, b;
	mpz_array array1, array2, array_expect;
	mpz_pool pool;

	pool_init(&pool, 0);
	array_init(&array1, 3);
	array_init(&array2, 3);
	array_init(&array_expect, 3);

	// primes: 577, 727, 863
	mpz_init_set_str(a, "577", 10);
	array_add(&array_expect, a);
	mpz_set_str(a, "727", 10);
	array_add(&array_expect, a);
	mpz_set_str(a, "863", 10);
	array_add(&array_expect, a);

	// `a = 727 * 577 = 419479`
	// `b = 727 * 863 = 627401`
	mpz_set_str(a, "419479", 10);
	mpz_init_set_str(b, "627401", 10);

	append_cb(&pool, &array1, a, b);
	if (mpz_cmp_ui(a, 419479) != 0) {
		return "append_cb has changed the input value a!";
	}
	if (mpz_cmp_ui(b, 627401) != 0) {
		return "append_cb has changed the input value b!";
	}

	array_msort(&array1);
	if (!array_equal(&array_expect, &array1)) {
		return "array1 and array_expect differ!";
	}

	append_cb(&pool, &array2, b, a);
	if (mpz_cmp_ui(a, 419479) != 0) {
		return "append_cb has changed the input value a!";
	}
	if (mpz_cmp_ui(b, 627401) != 0) {
		return "append_cb has changed the input value b!";
	}

	array_msort(&array2);
	if (!array_equal(&array_expect, &array2)) {
		return "array2 and array_expect differ!";
	}

	mpz_clear(a);
	mpz_clear(b);
	array_clear(&array1);
	array_clear(&array2);
	array_clear(&array_expect);
	pool_clear(&pool);

	return 0;
}
示例#2
0
// **TODO**: Add an test. This function shows only the usage of `append_cb`.
static char * test_multiple() {

	mpz_t a, b;
	mpz_array array1, array2, array_expect;
	mpz_pool pool;

	pool_init(&pool, 0);
	array_init(&array1, 3);
	array_init(&array2, 3);
	array_init(&array_expect, 3);

	// `30997 = 139 * 223`
	// `627401 = 727 * 863`
	// `182909 = 317 * 577`
	mpz_init_set_str(a, "30997", 10);
	array_add(&array_expect, a);
	mpz_set_str(a, "182909", 10);
	array_add(&array_expect, a);
	mpz_set_str(a, "627401", 10);
	array_add(&array_expect, a);

	// primes: 139, 223, 317, 577, 727, 863
	// `a = 139 * 223 * 317 * 577 = 5669630273`
	// `b = 317 * 577 * 727 * 863 = 114757289509`
	mpz_set_str(a, "5669630273", 10);
	mpz_init_set_str(b, "114757289509", 10);

	append_cb(&pool, &array1, a, b);
	array_msort(&array1);
	if (!array_equal(&array_expect, &array1)) {
		return "array1 and array_expect differ!";
	}

	append_cb(&pool, &array2, b, a);
	array_msort(&array2);
	if (!array_equal(&array_expect, &array2)) {
		return "array2 and array_expect differ!";
	}

	mpz_clear(a);
	mpz_clear(b);
	array_clear(&array1);
	array_clear(&array2);
	array_clear(&array_expect);
	pool_clear(&pool);

	return 0;
}
示例#3
0
sfpr_list_node_t *sfpr_list_append_with_cb(sfpr_list_t *list,void(*append_cb)(void*data, void* param),void* param,void *data)
{
	int len = 0;
	sfpr_list_node_t *node = NULL;
	
	if(list->pool){
		node = (sfpr_list_node_t *)sfpr_mem_malloc(list->pool,sizeof(sfpr_list_node_t));	/**< 申请链表节点存放数据*/		
	}else{
		node = (sfpr_list_node_t *)malloc(sizeof(sfpr_list_node_t));	/**< 申请链表节点存放数据*/
	}
	if (!node)
	{
		fprintf(stderr,"malloc failed!");
		return NULL;
	}
	node->data = data;	
	sfpr_mutex_lock(&list->mutex);	
	if (list->head == NULL) 		/**< 链表为空,插入表头*/
	{
		list->head = node;		
		list->tail = node;			
	}
	else
	{
		list->tail->next = node; 
		list->tail = list->tail->next;		
	}
	if(append_cb)
		append_cb(data, param);
	list->count++;
	list->tail->next = NULL;
	sfpr_mutex_unlock(&list->mutex);
	return node;	
}
示例#4
0
文件: copri.c 项目: jamella/copri
// This algorithm finds cb(P∪{b}) when P is coprime.
//
// Algorithm 16.2  [PDF page 21](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [cbextend test](test-cbextend.html) for basic usage.
void cbextend(mpz_array *ret, mpz_array *p, const mpz_t b) {
	size_t i;
	mpz_t x, a, r;
	mpz_array s;

	// **Sep 1**
	//
	//  If P = {}: Print b if b != 1. Stop.
	if (!p->used) {
		if (mpz_cmp_ui(b, 1) != 0) {
			array_add(ret, b);
		}
	}

	// **Sep 2**
	//
	//  Compute x ← prod P
	mpz_init(x);
	array_prod(p, x);

	// **Sep 3**
	//
	//   Compute (a,r) ← (ppi,ppo)(b, x) b
	mpz_init(a);
	mpz_init(r);
	ppi_ppo(a, r, b, x);

	// **Sep 4**
	//
	//   Print r if r != 1.
	if (mpz_cmp_ui(r, 1) != 0) {
		array_add(ret, r);
	}

	// **Sep 5**
	//
	//   Compute S ← split(a,P)
	array_init(&s, p->used);
	array_split(&s, a, p);

	// **Sep 6**
	//
	//   For each (p, c) ∈ S: Apply append_cb(p, c).
	if (p->used != s.used) {
		fprintf(stderr, "logic error in cbextend: p.used != s.used");
	} else {
		for (i = 0; i < p->used; i++) {
			append_cb(ret, p->array[i], s.array[i]);
		}
	}

	// Free the memory.
	array_clear(&s);
	mpz_clear(a);
	mpz_clear(r);
	mpz_clear(x);
}
示例#5
0
文件: copri.c 项目: jamella/copri
// Algorithm 13.2 [PDF page 17](http://cr.yp.to/lineartime/dcba-20040404.pdf)
//
// See [appendcb test](test-appendcb.html) for basic usage.
void append_cb(mpz_array *out, const mpz_t a, const mpz_t b) {

	mpz_t r, g, h, c, c0, x, y, d, b1, b2, a1;
	unsigned long long n;

	/* gmp_printf("enter append_cb(%Zd, %Zd)\n", a, b); */

	// **Step 1**
	//
	// If `b == 1` and `a == 1` add `a` to the array. If `b == 1` return.
	// This is the break condition of the recursive function.
	if (mpz_cmp_ui(b, 1) == 0) {
		if (mpz_cmp_ui(a, 1) != 0)  {
			array_add(out, a);
		}
		return;
	}

	mpz_init(r);
	mpz_init(g);
	mpz_init(a1);

	// **Step 2**
	//
	// Store ppi in `a1` and ppo in `r`. Use `a1` and not `a` to keep the input `const`
	// and handle the case that one parameter is used twice.
	ppi_ppo(a1, r, a, b);

	// **Step 3**
	//
	// If `r` (ppo) is **not** one add it to the array.
	if (mpz_cmp_ui(r, 1) != 0) {
		array_add(out, r);
	}

	mpz_init(h);
	mpz_init(c);

	// **Step 4**
	//
	// Caluclate the gcd, ppg and pple.
	gcd_ppg_pple(g, h, c, a1, b);

	// **Step 5**
	//
	// Store pple in `c0` and `x`.
	mpz_init_set(c0, c);
	mpz_init_set(x, c0);

	// **Step 6**
	//
	// Set `n` to one.
	n = 1;

	mpz_init(b1);
	mpz_init(b2);
	mpz_init(d);
	mpz_init(y);

	// Start while loop to be able to return to step 7.
	while(1) {
		// **Step 7**
		//
		// Compute (g, h, c) ← (gcd,ppg,pple)(h,g^2)
		mpz_mul(b1, g, g);
		mpz_set(b2, h);
		gcd_ppg_pple(g, h, c, b2, b1);

		// **Step 8**
		//
		// Compute d ← gcd(c, b)
		mpz_gcd(d, c, b);

		// **Step 9**
		//
		// Set x ← xd
		mpz_mul(x, x, d);

		// **Sep 10**
		//
		// Compute y ← d^2^	n−1.
		mpz_set(y, d);
		two_power(y, n - 1);

		// **Sep 11**
		//
		// Recursively apply (c/y,d).
		mpz_fdiv_q(b1, c, y);

		/* gmp_printf("rec call append_cb(%Zd, %Zd)\n", b1, d); */

		append_cb(out, b1, d);

		// **Sep 12**
		//
		// If h is not 1: Set n ← n+1. Return to Step 7.
		if (mpz_cmp_ui(h, 1) == 0) break;
		n = n + 1;
	}

	// **Step 13**
	//
	// Recursively apply (b/x, c0).
	mpz_fdiv_q(b1, b, x);
	append_cb(out, b1, c0);

	// Free the memory.
	mpz_clear(r);
	mpz_clear(g);
	mpz_clear(h);
	mpz_clear(c);
	mpz_clear(c0);
	mpz_clear(x);
	mpz_clear(y);
	mpz_clear(d);
	mpz_clear(b1);
	mpz_clear(b2);
	mpz_clear(a1);
}
示例#6
0
/*-------------------------------------------------------------------------
 * Function:    H5DOappend()
 *
 * Purpose:     To append elements to a dataset.
 *
 *      axis:       the dataset dimension (zero-based) for the append
 *      extension:  the # of elements to append for the axis-th dimension
 *      memtype:    the datatype
 *      buf:        buffer with data for the append
 *
 * Return:      Non-negative on success/Negative on failure
 *
 * Programmer:  Vailin Choi; Jan 2014
 *
 * Note:
 * 	This routine is copied from the fast forward feature branch: features/hdf5_ff
 *	src/H5FF.c:H5DOappend() with the following modifications:
 * 	1) Remove and replace macro calls such as
 *		FUNC_ENTER_API, H5TRACE, HGOTO_ERROR 
 * 	   accordingly because hl does not have these macros
 *	2) Replace H5I_get_type() by H5Iget_type()
 *	3) Replace H5P_isa_class() by H5Pisa_class()
 *	4) Fix a bug in the following: replace extension by size[axis]
 *		if(extension < old_size) {
 *		  ret_value = FAIL;
 *		  goto done;
 *   		}
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, 
           hid_t memtype, const void *buf)
{
    hbool_t created_dxpl = FALSE;       /* Whether we created a DXPL */
    hsize_t size[H5S_MAX_RANK];		/* The new size (after extension */
    hsize_t old_size = 0; 		/* The size of the dimension to be extended */
    int sndims; 			/* Number of dimensions in dataspace (signed) */
    unsigned ndims; 			/* Number of dimensions in dataspace */
    hid_t space_id = FAIL; 		/* Old file space */
    hid_t new_space_id = FAIL; 		/* New file space (after extension) */
    hid_t mem_space_id = FAIL; 		/* Memory space for data buffer */
    hssize_t snelmts; 			/* Number of elements in selection (signed) */
    hsize_t nelmts; 			/* Number of elements in selection */
    hid_t dapl = FAIL;			/* Dataset access property list */

    hsize_t start[H5S_MAX_RANK];	/* H5Sselect_Hyperslab: starting offset */
    hsize_t count[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of blocks to select */
    hsize_t stride[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of elements to move when selecting */
    hsize_t block[H5S_MAX_RANK];	/* H5Sselect_hyperslab: # of elements in a block */

    hsize_t *boundary = NULL;		/* Boundary set in append flush property */
    H5D_append_cb_t append_cb;		/* Callback function set in append flush property */
    void *udata;			/* User data set in append flush property */
    hbool_t hit = FALSE;		/* Boundary is hit or not */
    hsize_t k;				/* Local index variable */
    unsigned u; 		        /* Local index variable */
    herr_t ret_value = FAIL;		/* Return value */

    /* check arguments */
    if(H5I_DATASET != H5Iget_type(dset_id))
        goto done;

    /* If the user passed in a default DXPL, create one to pass to H5Dwrite() */
    if(H5P_DEFAULT == dxpl_id) {
        if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
            goto done;
        created_dxpl = TRUE;
    } /* end if */
    else if(TRUE != H5Pisa_class(dxpl_id, H5P_DATASET_XFER))
        goto done;

    /* Get the dataspace of the dataset */
    if(FAIL == (space_id = H5Dget_space(dset_id)))
        goto done;

    /* Get the rank of this dataspace */
    if((sndims = H5Sget_simple_extent_ndims(space_id)) < 0)
        goto done;
    ndims = (unsigned)sndims;

    /* Verify correct axis */
    if(axis >= ndims)
        goto done;

    /* Get the dimensions sizes of the dataspace */
    if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
        goto done;

    /* Adjust the dimension size of the requested dimension, 
     * but first record the old dimension size
     */
    old_size = size[axis];
    size[axis] += extension;
    if(size[axis] < old_size)
        goto done;

    /* Set the extent of the dataset to the new dimension */
    if(H5Dset_extent(dset_id, size) < 0)
        goto done;

    /* Get the new dataspace of the dataset */
    if(FAIL == (new_space_id = H5Dget_space(dset_id)))
        goto done;

    /* Select a hyperslab corresponding to the append operation */
    for(u = 0 ; u < ndims ; u++) {
        start[u] = 0;
        stride[u] = 1;
        count[u] = size[u];
        block[u] = 1;
        if(u == axis) {
            count[u] = extension;
            start[u] = old_size;
        } /* end if */
    } /* end for */
    if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block))
        goto done;

    /* The # of elemnts in the new extended dataspace */
    if((snelmts = H5Sget_select_npoints(new_space_id)) < 0)
        goto done;
    nelmts = (hsize_t)snelmts;

    /* create a memory space */
    if(FAIL == (mem_space_id = H5Screate_simple(1, &nelmts, NULL)))
        goto done;

    /* Write the data */
    if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0)
        goto done;

    /* Obtain the dataset's access property list */
    if((dapl = H5Dget_access_plist(dset_id)) < 0)
        goto done;

    /* Allocate the boundary array */
    boundary = (hsize_t *)HDmalloc(ndims * sizeof(hsize_t));

    /* Retrieve the append flush property */
    if(H5Pget_append_flush(dapl, ndims, boundary, &append_cb, &udata) < 0)
        goto done;

    /* No boundary for this axis */
    if(boundary[axis] != 0) {

        /* Determine whether a boundary is hit or not */
        for(k = start[axis]; k < size[axis]; k++)
            if(!((k + 1) % boundary[axis])) {
                hit = TRUE;
                break;
            }

        if(hit) { /* Hit the boundary */
            /* Invoke callback if there is one */
            if(append_cb && append_cb(dset_id, size, udata) < 0)
                goto done;

	        /* Do a dataset flush */
            if(H5Dflush(dset_id) < 0)
                goto done;
        } /* end if */
    } /* end if */

    /* Indicate success */
    ret_value = SUCCEED;

done:
    /* Close dxpl if we created it vs. one was passed in */
    if(created_dxpl) {
        if(H5Pclose(dxpl_id) < 0)
            ret_value = FAIL;
    } /* end if */

    /* Close old dataspace */
    if(space_id != FAIL && H5Sclose(space_id) < 0)
        ret_value = FAIL;

    /* Close new dataspace */
    if(new_space_id != FAIL && H5Sclose(new_space_id) < 0)
        ret_value = FAIL;

    /* Close memory dataspace */
    if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
        ret_value = FAIL;

    /* Close the dataset access property list */
    if(dapl != FAIL && H5Pclose(dapl) < 0)
        ret_value = FAIL;

    if(boundary)
        HDfree(boundary);

    return ret_value;
} /* H5DOappend() */