Пример #1
0
Datum
popc_or(PG_FUNCTION_ARGS)
{
	VarBit	   *arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *arg2 = PG_GETARG_VARBIT_P(1);
	bits8	   *ptr1 = VARBITS(arg1);
	bits8	   *ptr2 = VARBITS(arg2);
	int32		count = 0;
	int			offset = 0;
	int			bitlen;

	if (VARBITLEN(arg1) != VARBITLEN(arg2))
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("cannot AND bit strings of different sizes")));
#ifdef __GNUC__
	bitlen = LONGALIGN_DOWN(VARBITBYTES(arg1));

	for (offset=0; offset < bitlen; offset += sizeof(long))
		count += __builtin_popcountl(*((long *)(ptr1 + offset)) |
									 *((long *)(ptr2 + offset)));
#endif
	bitlen = VARBITBYTES(arg1);
	while (offset < bitlen)
	{
		count += bitcount_map[ptr1[offset] & ptr2[offset]];
		offset++;
	}
	PG_RETURN_INT32(count);
}
Пример #2
0
Datum
popc(PG_FUNCTION_ARGS)
{
	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
	bits8	   *ptr = VARBITS(arg);
	int32		count = 0;
	int			offset = 0;
	int			bitlen;

#ifdef __GNUC__
	bitlen = LONGALIGN_DOWN(VARBITBYTES(arg));

	for (offset=0; offset < bitlen; offset += sizeof(long))
		count +=  __builtin_popcountl(*((long *)(ptr + offset)));
#endif
	bitlen = VARBITBYTES(arg);
	while (offset < bitlen)
		count += bitcount_map[ptr[offset++]];

	PG_RETURN_INT32(count);
}
Пример #3
0
Datum
pgfadvise_loader(PG_FUNCTION_ARGS)
{
	Oid       relOid        = PG_GETARG_OID(0);
	text      *forkName     = PG_GETARG_TEXT_P(1);
	int       segmentNumber = PG_GETARG_INT32(2);
	bool      willneed      = PG_GETARG_BOOL(3);
	bool      dontneed      = PG_GETARG_BOOL(4);
	VarBit    *databit;

	/* our structure use to return values */
	pgfloaderStruct	*pgfloader;

	Relation  rel;
	char      *relationpath;
	char      filename[MAXPGPATH];

	/* our return value, 0 for success */
	int 			result;

	/*
	 * Postgresql stuff to return a tuple
	 */
	HeapTuple	tuple;
	TupleDesc	tupdesc;
	Datum		values[PGFADVISE_LOADER_COLS];
	bool		nulls[PGFADVISE_LOADER_COLS];

	if (PG_ARGISNULL(5))
		elog(ERROR, "pgfadvise_loader: databit argument shouldn't be NULL");

        databit		= PG_GETARG_VARBIT_P(5);

	/* initialize nulls array to build the tuple */
	memset(nulls, 0, sizeof(nulls));

	/* Build a tuple descriptor for our result type */
	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		elog(ERROR, "return type must be a row type");

	/* open the current relation in accessShareLock */
	rel = relation_open(relOid, AccessShareLock);

	/* we get the common part of the filename of each segment of a relation */
	relationpath = relpathpg(rel, forkName);

	/*
	 * If we are looking the first segment,
	 * relationpath should not be suffixed
	 */
	if (segmentNumber == 0)
		snprintf(filename,
		         MAXPGPATH,
		         "%s",
		         relationpath);
	else
		snprintf(filename,
		         MAXPGPATH,
		         "%s.%u",
		         relationpath,
		         (int) segmentNumber);

	/*
	 * We don't need the relation anymore
	 * the only purpose was to get a consistent filename
	 * (if file disappear, an error is logged)
	 */
	relation_close(rel, AccessShareLock);

	/*
	 * Call pgfadvise_loader with the varbit
	 */
	pgfloader = (pgfloaderStruct *) palloc(sizeof(pgfloaderStruct));
	result = pgfadvise_loader_file(filename,
								   willneed, dontneed, databit,
								   pgfloader);
	if (result != 0)
		elog(ERROR, "Can't read file %s, fork(%s)",
					filename, text_to_cstring(forkName));
	/* Filename */
	values[0] = CStringGetTextDatum( filename );
	/* os page size */
	values[1] = Int64GetDatum( pgfloader->pageSize );
	/* free page cache */
	values[2] = Int64GetDatum( pgfloader->pagesFree );
	/* pages loaded */
	values[3] = Int64GetDatum( pgfloader->pagesLoaded );
	/* pages unloaded  */
	values[4] = Int64GetDatum( pgfloader->pagesUnloaded );

	/* Build and return the result tuple. */
	tuple = heap_form_tuple(tupdesc, values, nulls);
	PG_RETURN_DATUM( HeapTupleGetDatum(tuple) );
}