Example #1
0
/*
*  truncates / compresses the node key
*  cpf_length .. common prefix length
*/
static GBT_VARKEY *
gbt_var_node_truncate(const GBT_VARKEY *node, int32 cpf_length, const gbtree_vinfo *tinfo)
{
	GBT_VARKEY *out = NULL;
	GBT_VARKEY_R r = gbt_var_key_readable(node);
	int32		len1 = VARSIZE(r.lower) - VARHDRSZ;
	int32		len2 = VARSIZE(r.upper) - VARHDRSZ;
	int32		si;
	char	   *out2;

	len1 = Min(len1, (cpf_length + 1));
	len2 = Min(len2, (cpf_length + 1));

	si = 2 * VARHDRSZ + INTALIGN(len1 + VARHDRSZ) + len2;
	out = (GBT_VARKEY *) palloc(si);
	SET_VARSIZE(out, si);

	memcpy(VARDATA(out), r.lower, len1 + VARHDRSZ);
	SET_VARSIZE(VARDATA(out), len1 + VARHDRSZ);

	out2 = VARDATA(out) + INTALIGN(len1 + VARHDRSZ);
	memcpy(out2, r.upper, len2 + VARHDRSZ);
	SET_VARSIZE(out2, len2 + VARHDRSZ);

	return out;
}
Example #2
0
/*
 * Create an entry to store in the index, from lower and upper bound.
 */
GBT_VARKEY *
gbt_var_key_copy(const GBT_VARKEY_R *u)
{
	int32		lowersize = VARSIZE(u->lower);
	int32		uppersize = VARSIZE(u->upper);
	GBT_VARKEY *r;

	r = (GBT_VARKEY *) palloc0(INTALIGN(lowersize) + uppersize + VARHDRSZ);
	memcpy(VARDATA(r), u->lower, lowersize);
	memcpy(VARDATA(r) + INTALIGN(lowersize), u->upper, uppersize);
	SET_VARSIZE(r, INTALIGN(lowersize) + uppersize + VARHDRSZ);

	return r;
}
static void BgwPoolMainLoop(Datum arg)
{
    BgwPoolExecutorCtx* ctx = (BgwPoolExecutorCtx*)arg;
    int id = ctx->id;
    BgwPool* pool = ctx->constructor();
    int size;
    void* work;

    BackgroundWorkerUnblockSignals();
	BackgroundWorkerInitializeConnection(pool->dbname, NULL);

    while(true) { 
        PGSemaphoreLock(&pool->available);
        SpinLockAcquire(&pool->lock);
        size = *(int*)&pool->queue[pool->head];
        Assert(size < pool->size);
        work = malloc(size);
        pool->pending -= 1;
        pool->active += 1;
		if (pool->lastPeakTime == 0 && pool->active == pool->nWorkers && pool->pending != 0) {
			pool->lastPeakTime = MtmGetSystemTime();
		}
        if (pool->head + size + 4 > pool->size) { 
            memcpy(work, pool->queue, size);
            pool->head = INTALIGN(size);
        } else { 
            memcpy(work, &pool->queue[pool->head+4], size);
            pool->head += 4 + INTALIGN(size);
        }
        if (pool->size == pool->head) { 
            pool->head = 0;
        }
        if (pool->producerBlocked) {
            pool->producerBlocked = false;
            PGSemaphoreUnlock(&pool->overflow);
			pool->lastPeakTime = 0;
        }
        SpinLockRelease(&pool->lock);
        pool->executor(id, work, size);
        free(work);
        SpinLockAcquire(&pool->lock);
        pool->active -= 1;
		pool->lastPeakTime = 0;
        SpinLockRelease(&pool->lock);
    }
}
void BgwPoolExecute(BgwPool* pool, void* work, size_t size)
{
    if (size+4 > pool->size) {
		/* 
		 * Size of work is larger than size of shared buffer: 
		 * run it immediately
		 */
		pool->executor(0, work, size);
		return;
	}
 
    SpinLockAcquire(&pool->lock);
    while (true) { 
        if ((pool->head <= pool->tail && pool->size - pool->tail < size + 4 && pool->head < size) 
            || (pool->head > pool->tail && pool->head - pool->tail < size + 4))
        {
            if (pool->lastPeakTime == 0) {
				pool->lastPeakTime = MtmGetSystemTime();
			}
			pool->producerBlocked = true;
            SpinLockRelease(&pool->lock);
            PGSemaphoreLock(&pool->overflow);
            SpinLockAcquire(&pool->lock);
        } else {
            pool->pending += 1;
			if (pool->lastPeakTime == 0 && pool->active == pool->nWorkers && pool->pending != 0) {
				pool->lastPeakTime = MtmGetSystemTime();
			}
            *(int*)&pool->queue[pool->tail] = size;
            if (pool->size - pool->tail >= size + 4) { 
                memcpy(&pool->queue[pool->tail+4], work, size);
                pool->tail += 4 + INTALIGN(size);
            } else { 
                memcpy(pool->queue, work, size);
                pool->tail = INTALIGN(size);
            }
            if (pool->tail == pool->size) {
                pool->tail = 0;
            }
            PGSemaphoreUnlock(&pool->available);
            break;
        }
    }
    SpinLockRelease(&pool->lock);            
}
Example #5
0
Datum domainname_parts(PG_FUNCTION_ARGS)
{
	text *in = PG_GETARG_TEXT_P(0);
	const char *s = VARDATA(in);
	const char *b = s, *p = s, *e = s + VARSIZE_ANY_EXHDR(in);
	int nelems = 0;
	int nbytes = ARR_OVERHEAD_NONULLS(1);
	ArrayType *r;
	char *o;

	while (p < e) 
	{
		b = p;
		STRSEARCH(p, e-p, *p == '.');
		nelems ++;
		nbytes += VARHDRSZ + (p-b);
		nbytes = INTALIGN(nbytes);
		p ++;
	}
	r = (ArrayType *)palloc(nbytes);
	SET_VARSIZE(r, nbytes);
	r->ndim = 1;
	r->dataoffset = 0;
	r->elemtype = TEXTOID;
	*ARR_DIMS(r) = nelems;
	*ARR_LBOUND(r) = 1;

	p = s;
	o = ARR_DATA_PTR(r);
	while (p < e)
	{
		b = p;
		STRSEARCH(p, e-p, *p == '.');
		SET_VARSIZE(o, VARHDRSZ+(p-b));
		o = VARDATA(o);
		memcpy(o, b, p-b);
		o += INTALIGN(p-b);
		p ++;
	}

	PG_FREE_IF_COPY(in, 0);
	PG_RETURN_ARRAYTYPE_P(r);
}
Example #6
0
static bytea *
gbt_bit_xfrm(bytea *leaf)
{
	bytea	   *out = leaf;
	int			s = INTALIGN(VARBITBYTES(leaf) + VARHDRSZ);

	out = palloc(s);
	SET_VARSIZE(out, s);
	memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
	return out;
}
Example #7
0
GBT_VARKEY *
gbt_var_key_copy(const GBT_VARKEY_R *u, bool force_node)
{
	GBT_VARKEY *r = NULL;

	if (u->lower == u->upper && !force_node)
	{							/* leaf key mode */
		r = (GBT_VARKEY *) palloc(VARSIZE(u->lower) + VARHDRSZ);
		memcpy(VARDATA(r), u->lower, VARSIZE(u->lower));
		SET_VARSIZE(r, VARSIZE(u->lower) + VARHDRSZ);
	}
	else
	{							/* node key mode  */
		r = (GBT_VARKEY *) palloc(INTALIGN(VARSIZE(u->lower)) + VARSIZE(u->upper) + VARHDRSZ);
		memcpy(VARDATA(r), u->lower, VARSIZE(u->lower));
		memcpy(VARDATA(r) + INTALIGN(VARSIZE(u->lower)), u->upper, VARSIZE(u->upper));
		SET_VARSIZE(r, INTALIGN(VARSIZE(u->lower)) + VARSIZE(u->upper) + VARHDRSZ);
	}
	return r;
}
Example #8
0
GBT_VARKEY_R
gbt_var_key_readable(const GBT_VARKEY *k)
{
	GBT_VARKEY_R r;

	r.lower = (bytea *) &(((char *) k)[VARHDRSZ]);
	if (VARSIZE(k) > (VARHDRSZ + (VARSIZE(r.lower))))
		r.upper = (bytea *) &(((char *) k)[VARHDRSZ + INTALIGN(VARSIZE(r.lower))]);
	else
		r.upper = r.lower;
	return r;
}
Example #9
0
static bytea *
gbt_bit_xfrm(bytea *leaf)
{
	bytea	   *out = leaf;
	int			sz = VARBITBYTES(leaf) + VARHDRSZ;
	int			padded_sz = INTALIGN(sz);

	out = (bytea *) palloc(padded_sz);
	/* initialize the padding bytes to zero */
	while (sz < padded_sz)
		((char *) out)[sz++] = 0;
	SET_VARSIZE(out, padded_sz);
	memcpy((void *) VARDATA(out), (void *) VARBITS(leaf), VARBITBYTES(leaf));
	return out;
}
Example #10
0
static PCPATCH *
pcpatch_from_point_array(ArrayType *array, FunctionCallInfoData *fcinfo)
{
	int nelems;
	bits8 *bitmap;
	int bitmask;
	size_t offset = 0;
	int i;
    uint32 pcid = 0;
	PCPATCH *pa;
	PCPOINTLIST *pl;
    PCSCHEMA *schema = 0;

	/* How many things in our array? */
	nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));

	/* PgSQL supplies a bitmap of which array entries are null */
	bitmap = ARR_NULLBITMAP(array);

	/* Empty array? Null return */
	if ( nelems == 0 ) 
        return NULL;
	
	/* Make our holder */
	pl = pc_pointlist_make(nelems);

	offset = 0;
	bitmap = ARR_NULLBITMAP(array);
	bitmask = 1;
	for ( i = 0; i < nelems; i++ )
	{
		/* Only work on non-NULL entries in the array */
		if ( ! array_get_isnull(bitmap, i) )
		{
			SERIALIZED_POINT *serpt = (SERIALIZED_POINT *)(ARR_DATA_PTR(array)+offset);
			PCPOINT *pt;
			
			if ( ! schema )
			{
                schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
		    }
			
			if ( ! pcid ) 
			{
				pcid = serpt->pcid;
			}
			else if ( pcid != serpt->pcid )
			{
				elog(ERROR, "pcpatch_from_point_array: pcid mismatch (%d != %d)", serpt->pcid, pcid);
			}
			
			pt = pc_point_deserialize(serpt, schema);
			if ( ! pt )
			{
				elog(ERROR, "pcpatch_from_point_array: point deserialization failed");
			}
			
			pc_pointlist_add_point(pl, pt);

			offset += INTALIGN(VARSIZE(serpt));			
		}

	}
	
	if ( pl->npoints == 0 )
		return NULL;

	pa = pc_patch_from_pointlist(pl);
	pc_pointlist_free(pl);
    return pa;
}
Example #11
0
static PCPATCH *
pcpatch_from_patch_array(ArrayType *array, FunctionCallInfoData *fcinfo)
{
	int nelems;
	bits8 *bitmap;
	int bitmask;
	size_t offset = 0;
	int i;
    uint32 pcid = 0;
	PCPATCH *pa;
	PCPATCH **palist;
    int numpatches = 0;
    PCSCHEMA *schema = 0;

	/* How many things in our array? */
	nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));

	/* PgSQL supplies a bitmap of which array entries are null */
	bitmap = ARR_NULLBITMAP(array);

	/* Empty array? Null return */
	if ( nelems == 0 ) 
        return NULL;
	
	/* Make our temporary list of patches */
	palist = pcalloc(nelems*sizeof(PCPATCH*));

    /* Read the patches out of the array and deserialize */
	offset = 0;
	bitmap = ARR_NULLBITMAP(array);
	bitmask = 1;
	for ( i = 0; i < nelems; i++ )
	{
		/* Only work on non-NULL entries in the array */
		if ( ! array_get_isnull(bitmap, i) )
		{
			SERIALIZED_PATCH *serpatch = (SERIALIZED_PATCH *)(ARR_DATA_PTR(array)+offset);
			
			if ( ! schema )
			{
                schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
		    }
			
			if ( ! pcid ) 
			{
				pcid = serpatch->pcid;
			}
			else if ( pcid != serpatch->pcid )
			{
				elog(ERROR, "pcpatch_from_patch_array: pcid mismatch (%d != %d)", serpatch->pcid, pcid);
			}
			
			pa = pc_patch_deserialize(serpatch, schema);
			if ( ! pa )
			{
				elog(ERROR, "pcpatch_from_patch_array: patch deserialization failed");
			}
			
            palist[numpatches++] = pa;

			offset += INTALIGN(VARSIZE(serpatch));
		}

	}
	
	/* Can't do anything w/ NULL */
	if ( numpatches == 0 )
		return NULL;

    /* Pass to the lib to build the output patch from the list */
	pa = pc_patch_from_patchlist(palist, numpatches);
	
	/* Free the temporary patch list */
    for ( i = 0; i < numpatches; i++ )
    {
        pc_patch_free(palist[i]);
    }
    pcfree(palist);
    
    return pa;
}
Example #12
0
static int32
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
{
    HeapTuple typ_tuple;
    TypeTupleForm typ_struct;
    bool typbyval;
    int typlen;
    func_ptr proc_fn;
    int pronargs;
    int nitems, i, result;
    int ndim, *dim;
    char *p;

    /* Sanity checks */
    if ((array == (ArrayType *) NULL)
	|| (ARR_IS_LO(array) == true)) {
	/* elog(NOTICE, "array_iterator: array is null"); */
        return (0);
    }
    ndim = ARR_NDIM(array);
    dim = ARR_DIMS(array);
    nitems = getNitems(ndim, dim);
    if (nitems == 0) {
	/* elog(NOTICE, "array_iterator: nitems = 0"); */
        return (0);
    }

    /* Lookup element type information */
    typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype),0,0,0);
    if (!HeapTupleIsValid(typ_tuple)) {
        elog(WARN,"array_iterator: cache lookup failed for type %d", elemtype);
        return 0;
    }
    typ_struct = (TypeTupleForm) GETSTRUCT(typ_tuple);
    typlen   = typ_struct->typlen;
    typbyval = typ_struct->typbyval;

    /* Lookup the function entry point */
    proc_fn == (func_ptr) NULL;
    fmgr_info(proc, &proc_fn, &pronargs);
    if ((proc_fn == NULL) || (pronargs != 2)) {
	elog(WARN, "array_iterator: fmgr_info lookup failed for oid %d", proc);
        return (0);
    }

    /* Scan the array and apply the operator to each element */
    result = 0;
    p = ARR_DATA_PTR(array);
    for (i = 0; i < nitems; i++) {
        if (typbyval) {
            switch(typlen) {
	      case 1:
		result = (int) (*proc_fn)(*p, value);
		break;
	    case 2:
		result = (int) (*proc_fn)(* (int16 *) p, value);
		break;
	    case 3:
	    case 4:
		result = (int) (*proc_fn)(* (int32 *) p, value);
		break;
            }
            p += typlen;
        } else {
	    result = (int) (*proc_fn)(p, value);
            if (typlen > 0) {
		p += typlen;
	    } else {
                p += INTALIGN(* (int32 *) p);
	    }
        }
	if (result) {
	    if (!and) {
		return (1);
	    }
	} else {
	    if (and) {
		return (0);
	    }
	}
    }

    if (and && result) {
	return (1);
    } else {
	return (0);
    }
}