⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gistproc.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
			cur = DatumGetBoxP(entryvec->vector[i].key);			avgCenterX += ((double) cur->high.x + (double) cur->low.x) / 2.0;			avgCenterY += ((double) cur->high.y + (double) cur->low.y) / 2.0;		}		avgCenterX /= maxoff;		avgCenterY /= maxoff;		posL = posR = posB = posT = 0;		for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))		{			cur = DatumGetBoxP(entryvec->vector[i].key);			CenterX = ((double) cur->high.x + (double) cur->low.x) / 2.0;			CenterY = ((double) cur->high.y + (double) cur->low.y) / 2.0;			if (CenterX < avgCenterX)				ADDLIST(listL, unionL, posL, i);			else if (CenterX == avgCenterX)			{				if (posL > posR)					ADDLIST(listR, unionR, posR, i);				else					ADDLIST(listL, unionL, posL, i);			}			else				ADDLIST(listR, unionR, posR, i);			if (CenterY < avgCenterY)				ADDLIST(listB, unionB, posB, i);			else if (CenterY == avgCenterY)			{				if (posB > posT)					ADDLIST(listT, unionT, posT, i);				else					ADDLIST(listB, unionB, posB, i);			}			else				ADDLIST(listT, unionT, posT, i);		}	}	/* which split more optimal? */	if (Max(posL, posR) < Max(posB, posT))		direction = 'x';	else if (Max(posL, posR) > Max(posB, posT))		direction = 'y';	else	{		Datum		interLR = DirectFunctionCall2(rt_box_inter,												  BoxPGetDatum(unionL),												  BoxPGetDatum(unionR));		Datum		interBT = DirectFunctionCall2(rt_box_inter,												  BoxPGetDatum(unionB),												  BoxPGetDatum(unionT));		double		sizeLR,					sizeBT;		sizeLR = size_box(interLR);		sizeBT = size_box(interBT);		if (sizeLR < sizeBT)			direction = 'x';		else			direction = 'y';	}	if (direction == 'x')		chooseLR(v,				 listL, posL, unionL,				 listR, posR, unionR);	else		chooseLR(v,				 listB, posB, unionB,				 listT, posT, unionT);	PG_RETURN_POINTER(v);}/* * Equality method */Datumgist_box_same(PG_FUNCTION_ARGS){	BOX		   *b1 = PG_GETARG_BOX_P(0);	BOX		   *b2 = PG_GETARG_BOX_P(1);	bool	   *result = (bool *) PG_GETARG_POINTER(2);	if (b1 && b2)		*result = DatumGetBool(DirectFunctionCall2(box_same,												   PointerGetDatum(b1),												   PointerGetDatum(b2)));	else		*result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE;	PG_RETURN_POINTER(result);}/* * Leaf-level consistency for boxes: just apply the query operator */static boolgist_box_leaf_consistent(BOX *key, BOX *query, StrategyNumber strategy){	bool		retval;	switch (strategy)	{		case RTLeftStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_left,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverLeftStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overleft,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverlapStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overlap,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverRightStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overright,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTRightStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_right,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTSameStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_same,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTContainsStrategyNumber:		case RTOldContainsStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_contain,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTContainedByStrategyNumber:		case RTOldContainedByStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_contained,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverBelowStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overbelow,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTBelowStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_below,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTAboveStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_above,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverAboveStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overabove,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		default:			retval = FALSE;	}	return retval;}static doublesize_box(Datum dbox){	BOX		   *box = DatumGetBoxP(dbox);	if (box == NULL || box->high.x <= box->low.x || box->high.y <= box->low.y)		return 0.0;	return (box->high.x - box->low.x) * (box->high.y - box->low.y);}/***************************************** * Common rtree functions (for boxes, polygons, and circles) *****************************************//* * Internal-page consistency for all these types * * We can use the same function since all types use bounding boxes as the * internal-page representation. */static boolrtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy){	bool		retval;	switch (strategy)	{		case RTLeftStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_overright,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverLeftStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_right,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverlapStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overlap,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverRightStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_left,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTRightStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_overleft,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTSameStrategyNumber:		case RTContainsStrategyNumber:		case RTOldContainsStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_contain,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTContainedByStrategyNumber:		case RTOldContainedByStrategyNumber:			retval = DatumGetBool(DirectFunctionCall2(box_overlap,													  PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverBelowStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_above,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTBelowStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_overabove,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTAboveStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_overbelow,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		case RTOverAboveStrategyNumber:			retval = !DatumGetBool(DirectFunctionCall2(box_below,													   PointerGetDatum(key),													PointerGetDatum(query)));			break;		default:			retval = FALSE;	}	return retval;}/************************************************** * Polygon ops **************************************************//* * GiST compress for polygons: represent a polygon by its bounding box */Datumgist_poly_compress(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	GISTENTRY  *retval;	if (entry->leafkey)	{		retval = palloc(sizeof(GISTENTRY));		if (DatumGetPointer(entry->key) != NULL)		{			POLYGON    *in = DatumGetPolygonP(entry->key);			BOX		   *r;			r = (BOX *) palloc(sizeof(BOX));			memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX));			gistentryinit(*retval, PointerGetDatum(r),						  entry->rel, entry->page,						  entry->offset, FALSE);		}		else		{			gistentryinit(*retval, (Datum) 0,						  entry->rel, entry->page,						  entry->offset, FALSE);		}	}	else		retval = entry;	PG_RETURN_POINTER(retval);}/* * The GiST Consistent method for polygons */Datumgist_poly_consistent(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	POLYGON    *query = PG_GETARG_POLYGON_P(1);	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);	bool		result;	if (DatumGetBoxP(entry->key) == NULL || query == NULL)		PG_RETURN_BOOL(FALSE);	/*	 * Since the operators are marked lossy anyway, we can just use	 * rtree_internal_consistent even at leaf nodes.  (This works in part	 * because the index entries are bounding boxes not polygons.)	 */	result = rtree_internal_consistent(DatumGetBoxP(entry->key),									   &(query->boundbox), strategy);	/* Avoid memory leak if supplied poly is toasted */	PG_FREE_IF_COPY(query, 1);	PG_RETURN_BOOL(result);}/************************************************** * Circle ops **************************************************//* * GiST compress for circles: represent a circle by its bounding box */Datumgist_circle_compress(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	GISTENTRY  *retval;	if (entry->leafkey)	{		retval = palloc(sizeof(GISTENTRY));		if (DatumGetCircleP(entry->key) != NULL)		{			CIRCLE	   *in = DatumGetCircleP(entry->key);			BOX		   *r;			r = (BOX *) palloc(sizeof(BOX));			r->high.x = in->center.x + in->radius;			r->low.x = in->center.x - in->radius;			r->high.y = in->center.y + in->radius;			r->low.y = in->center.y - in->radius;			gistentryinit(*retval, PointerGetDatum(r),						  entry->rel, entry->page,						  entry->offset, FALSE);		}		else		{			gistentryinit(*retval, (Datum) 0,						  entry->rel, entry->page,						  entry->offset, FALSE);		}	}	else		retval = entry;	PG_RETURN_POINTER(retval);}/* * The GiST Consistent method for circles */Datumgist_circle_consistent(PG_FUNCTION_ARGS){	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);	CIRCLE	   *query = PG_GETARG_CIRCLE_P(1);	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);	BOX			bbox;	bool		result;	if (DatumGetBoxP(entry->key) == NULL || query == NULL)		PG_RETURN_BOOL(FALSE);	/*	 * Since the operators are marked lossy anyway, we can just use	 * rtree_internal_consistent even at leaf nodes.  (This works in part	 * because the index entries are bounding boxes not circles.)	 */	bbox.high.x = query->center.x + query->radius;	bbox.low.x = query->center.x - query->radius;	bbox.high.y = query->center.y + query->radius;	bbox.low.y = query->center.y - query->radius;	result = rtree_internal_consistent(DatumGetBoxP(entry->key),									   &bbox, strategy);	PG_RETURN_BOOL(result);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -