Esempio n. 1
0
/*
 * pvector_pop_back -- decreases the number of values and executes
 *	a user-defined callback in which the caller must zero the value.
 */
uint64_t
pvector_pop_back(struct pvector_context *ctx, entry_op_callback cb)
{
	if (ctx->nvalues == 0)
		return 0;

	uint64_t idx = ctx->nvalues - 1;
	struct array_spec s = pvector_get_array_spec(idx);

	uint64_t *arrp = OBJ_OFF_TO_PTR(ctx->pop, ctx->vec->arrays[s.idx]);
	uint64_t ret = arrp[s.pos];

	if (cb)
		cb(ctx->pop, &arrp[s.pos]);

	if (s.pos == 0 && s.idx != 0 /* the array 0 is embedded */) {
#ifdef USE_VG_PMEMCHECK
		if (On_valgrind) {
			size_t usable_size = sizeof(uint64_t) *
				(1ULL << (s.idx + PVECTOR_INIT_SHIFT));
			VALGRIND_REMOVE_FROM_TX(arrp, usable_size);
		}
#endif
		pfree(ctx->pop, &ctx->vec->arrays[s.idx]);
	}

	ctx->nvalues--;

	return ret;
}
Esempio n. 2
0
/*
 * pvector_get -- returns the vector value at the index.
 */
static uint64_t
pvector_get(PMEMobjpool *pop, struct pvector *vec, uint64_t idx)
{
	struct array_spec s = pvector_get_array_spec(idx);
	uint64_t *arrp = OBJ_OFF_TO_PTR(pop, vec->arrays[s.idx]);

	return arrp[s.pos];
}
Esempio n. 3
0
/*
 * pvector_push_back -- bumps the number of values in the vector and returns
 *	the pointer to the value position to which the caller must set the
 *	value. Calling this method without actually setting the value will
 *	result in an inconsistent vector state.
 */
uint64_t *
pvector_push_back(struct pvector_context *ctx)
{
	uint64_t idx = ctx->nvalues;
	struct array_spec s = pvector_get_array_spec(idx);
	if (s.idx >= PVECTOR_MAX_ARRAYS) {
		ERR("Exceeded maximum number of entries in persistent vector");
		return NULL;
	}
	PMEMobjpool *pop = ctx->pop;

	/*
	 * If the destination array does not exist, calculate its size
	 * and allocate it.
	 */
	if (ctx->vec->arrays[s.idx] == 0) {
		if (s.idx == 0) {
			/*
			 * In the case the vector is completely empty the
			 * initial embedded array must be assigned as the first
			 * element of the sequence.
			 */
			ASSERTeq(util_is_zeroed(ctx->vec,
				sizeof(*ctx->vec)), 1);

			ctx->vec->arrays[0] = OBJ_PTR_TO_OFF(pop,
				&ctx->vec->embedded);

			pmemops_persist(&pop->p_ops, &ctx->vec->arrays[0],
				sizeof(ctx->vec->arrays[0]));
		} else {
			size_t arr_size = sizeof(uint64_t) *
				(1ULL << (s.idx + PVECTOR_INIT_SHIFT));

			if (pmalloc_construct(pop,
				&ctx->vec->arrays[s.idx],
				arr_size, pvector_array_constr, NULL,
				0, OBJ_INTERNAL_OBJECT_MASK, 0) != 0)
					return NULL;
		}
	}

	ctx->nvalues++;
	uint64_t *arrp = OBJ_OFF_TO_PTR(pop, ctx->vec->arrays[s.idx]);

	return &arrp[s.pos];
}