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

📄 rvgraph.c

📁 h.248协议源码
💻 C
字号:
/******************************************************************************
Filename:    rvgraph.c
Description: graph class
*******************************************************************************
                Copyright (c) 2000 RADVision Inc.
*******************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
******************************************************************************/

#include "rvgraph.h"

static RvGraphLink *rvGraphLinkConstruct(RvGraphLink *link, RvGraphNode *node, void *data)
{
	link->node = node;
	link->data = data;
	return link;
}

#define rvGraphLinkConstructCopy rvDefaultConstructCopy
#define rvGraphLinkDestruct rvDefaultDestruct

static RvBool rvGraphLinkEqual(const RvGraphLink *a, const RvGraphLink *b)
{
	return a->node == b->node && a->data == b->data;
}

#define rvGraphLinkGetNode(x) ((x)->node)
#define rvGraphLinkGetData(x) ((x)->data)
#define RvGraphLinkConstructCopy rvGraphLinkConstructCopy
#define RvGraphLinkDestruct rvGraphLinkDestruct
#define RvGraphLinkEqual rvGraphLinkEqual

rvDefineList(RvGraphLink)

static RvGraphNode *rvGraphNodeConstruct(RvGraphNode *node, void *item, RvAlloc *alloc)
{
	node->item = item;
	rvListConstruct(RvGraphLink)(&node->out, alloc);
	rvListConstruct(RvGraphLink)(&node->in, alloc);
	return node;
}

static RvGraphNode *rvGraphNodeConstructCopy(RvGraphNode *d, const RvGraphNode *s, RvAlloc *alloc)
{
	d->item = s->item;
	rvListConstructCopy(RvGraphLink)(&d->out, &s->out, alloc);
	rvListConstructCopy(RvGraphLink)(&d->in, &s->in, alloc);
	return d;
}

static void rvGraphNodeDestruct(RvGraphNode *node)
{
	rvListDestruct(RvGraphLink)(&node->out);
	rvListDestruct(RvGraphLink)(&node->in);
}

static RvBool rvGraphNodeEqual(const RvGraphNode *a, const RvGraphNode *b)
{
	return a == b;
}

#define RvGraphNodeConstructCopy rvGraphNodeConstructCopy
#define RvGraphNodeDestruct rvGraphNodeDestruct
#define RvGraphNodeEqual rvGraphNodeEqual

rvDefineList(RvGraphNode)

RvGraph *rvGraphConstructA(RvGraph *graph, RvAlloc *alloc)
{
	rvListConstruct(RvGraphNode)(&graph->nodes, alloc);
	return graph;
}

static RvBool addLinkToGraph(void *head, void *tail, void *link, void *data)
{
	rvGraphAddLink((RvGraph *)data, head, tail, link);
	return rvFalse;
}

RvGraph *rvGraphConstructCopy(RvGraph *d, const RvGraph *s, RvAlloc *alloc)
{
	rvGraphConstructA(d, alloc);
	rvGraphForEachLink((RvGraph *)s, addLinkToGraph, d);
	return d;
}

void rvGraphDestruct(RvGraph *graph)
{
	rvListDestruct(RvGraphNode)(&graph->nodes);
}

RvGraph *rvGraphCopy(RvGraph *d, const RvGraph *s)
{
	rvGraphClear(d);
	rvGraphForEachLink((RvGraph *)s, addLinkToGraph, d);
	return d;
}

void rvGraphAddNode(RvGraph *graph, void *node)
{
	RvGraphNode n;
	rvGraphNodeConstruct(&n, node, rvGraphGetAllocator(graph));
	rvListPushBack(RvGraphNode)(&graph->nodes, &n);
	rvGraphNodeDestruct(&n);
}

static RvBool linkCmp(void *link, void *data) {
	return (link==data);
}

static void removeLinkCmp(RvList(RvGraphLink) *list, void *node,RvGraphLinkCmpFunc f,void *data)
{
	RvGraphLinkIter i;
	for(i=rvListBegin(list); i!=rvListEnd(list); i=rvListIterNext(i))
	{
		if(rvGraphLinkIterGetNode(i) == node && f(rvGraphLinkIterGetData(i),data)==rvTrue )
		{
			rvListErase(RvGraphLink)(list, i);
			return;
		}
	}
}

static void removeLink(RvList(RvGraphLink) *list, void *node, void *data)
{
	removeLinkCmp(list,node,linkCmp,data);
}

void rvGraphRemoveNodeIter(RvGraph *graph, RvGraphNodeIter nodeIter,RvGraphLinkFunc f,void * data)
{
	void * node = rvGraphNodeIterGetNode(nodeIter);
	if(nodeIter != rvGraphEnd(graph))
	{
		RvGraphLinkIter i;
		for(i=rvGraphNodeOutLinksBegin(nodeIter); i!=rvGraphNodeOutLinksEnd(nodeIter); i=rvGraphLinkIterNext(i))
		{
			RvGraphLink *link = rvListIterData(i);
			void * linkData = rvGraphLinkGetData(link);
			removeLink(&rvGraphLinkGetNode(link)->in, node,linkData ); 
			/* Post-process the link data (i.e.,release */
			f(node,&rvGraphLinkGetNode(link)->in,linkData,data);
		}
		for(i=rvGraphNodeInLinksBegin(nodeIter); i!=rvGraphNodeInLinksEnd(nodeIter); i=rvGraphLinkIterNext(i))
		{
			RvGraphLink *link = rvListIterData(i);
			void * linkData = rvGraphLinkGetData(link);
			removeLink(&rvGraphLinkGetNode(link)->out, node, linkData); 
			/* Post-process the link data (i.e.,release */
			f(&rvGraphLinkGetNode(link)->out,node,linkData,data);
		}
		rvListErase(RvGraphNode)(&graph->nodes, nodeIter);
	}
}

static RvBool nullLinkFunc(void *head, void *tail, void *link, void *data) {
	return rvTrue;
}

void rvGraphRemoveNode(RvGraph *graph, void *node)
{
	rvGraphRemoveNodeExt(graph,node,nullLinkFunc,0);
}

void rvGraphRemoveNodeExt(RvGraph *graph, void *node,RvGraphLinkFunc f,void * data)
{
	RvGraphNodeIter nodeIter = rvGraphFindNode(graph, node);
	rvGraphRemoveNodeIter(graph,nodeIter,f,data);
}

void rvGraphClear(RvGraph *graph)
{
	rvListClear(RvGraphNode)(&graph->nodes);
}

void rvGraphAddLink(RvGraph *graph, void *head, void *tail, void *data)
{
	RvGraphNodeIter headIter, tailIter;
	RvGraphLink fwlink, bwlink;
	if((headIter = rvGraphFindNode(graph, head)) == rvGraphEnd(graph))
	{
		rvGraphAddNode(graph, head);
		headIter = rvGraphNodeIterPrev(rvGraphEnd(graph));
	}
	if((tailIter = rvGraphFindNode(graph, tail)) == rvGraphEnd(graph))
	{
		rvGraphAddNode(graph, tail);
		tailIter = rvGraphNodeIterPrev(rvGraphEnd(graph));
	}
	rvGraphLinkConstruct(&fwlink, rvListIterData(tailIter), data);
	rvGraphLinkConstruct(&bwlink, rvListIterData(headIter), data);
	rvListPushBack(RvGraphLink)(&rvListIterData(headIter)->out, &fwlink);
	rvListPushBack(RvGraphLink)(&rvListIterData(tailIter)->in, &bwlink);
	rvGraphLinkDestruct(&fwlink);
	rvGraphLinkDestruct(&bwlink);
}

void rvGraphRemoveLinkCmp(RvGraph *graph, void *head, void *tail,RvGraphLinkCmpFunc f,void *data) 
{
	RvGraphNodeIter headIter = rvGraphFindNode(graph, head);
	RvGraphNodeIter tailIter = rvGraphFindNode(graph, tail);
	if(headIter != rvGraphEnd(graph) && tailIter != rvGraphEnd(graph))
	{
		removeLinkCmp(&rvListIterData(headIter)->out, tail,f,data);
		removeLinkCmp(&rvListIterData(tailIter)->in, head,f,data);
	}
}

void rvGraphRemoveLink(RvGraph *graph, void *head, void *tail, void *data)
{
	rvGraphRemoveLinkCmp(graph,head,tail,linkCmp,data);
}

void rvGraphClearLinks(RvGraph *graph)
{
	RvGraphNodeIter i;
	for(i=rvGraphBegin(graph); i!=rvGraphEnd(graph); i=rvGraphNodeIterNext(i))
	{
		RvGraphNode *node = rvListIterData(i);
		rvListClear(RvGraphLink)(&node->out);
		rvListClear(RvGraphLink)(&node->in);
	}
}

size_t rvGraphGetNumNodes(RvGraph *graph)
{
	return rvListSize(&graph->nodes);
}

RvGraphNodeIter rvGraphBegin(RvGraph *graph)
{
	return rvListBegin(&graph->nodes);
}

RvGraphNodeIter rvGraphTail(RvGraph *graph)
{
	return rvListRevBegin(&graph->nodes);
}

RvGraphNodeIter rvGraphEnd(RvGraph *graph)
{
	return rvListEnd(&graph->nodes);
}


RvGraphNodeIter rvGraphFindNodeIterCmp(RvGraph *graph, RvGraphNodeFunc f,void * data)
{
	RvGraphNodeIter i;
	for(i=rvGraphBegin(graph);i!=rvGraphEnd(graph);i=rvGraphNodeIterNext(i)) {
		if(	f(rvGraphNodeIterGetNode(i),data)== rvTrue )
			return i;
	}
		;
	return i;
}

static RvBool nodeCmp(void *node, void *data) 
{
	return (node==data);
}

RvGraphNodeIter rvGraphFindNode(RvGraph *graph, void *node)
{
	return rvGraphFindNodeIterCmp(graph,nodeCmp,node);
}

void * rvGraphFindNodeCmp(RvGraph *graph, RvGraphNodeFunc f,void * data) {
	RvGraphNodeIter i = rvGraphFindNodeIterCmp(graph,f,data);
	if( i==rvGraphEnd(graph) )
		return NULL;
	return rvGraphNodeIterGetNode(i);
}

RvGraphLinkIter rvGraphNodeOutLinksBegin(RvGraphNodeIter i)
{
	return rvListBegin(&rvListIterData(i)->out);
}

RvGraphLinkIter rvGraphNodeOutLinksEnd(RvGraphNodeIter i)
{
	return rvListEnd(&rvListIterData(i)->out);
}

RvGraphLinkIter rvGraphNodeInLinksBegin(RvGraphNodeIter i)
{
	return rvListBegin(&rvListIterData(i)->in);
}

RvGraphLinkIter rvGraphNodeInLinksEnd(RvGraphNodeIter i)
{
	return rvListEnd(&rvListIterData(i)->in);
}


size_t rvGraphNodeGetNumOutLinks(RvGraphNodeIter i)
{
	return rvListSize(&rvListIterData(i)->out);
}

size_t rvGraphNodeGetNumInLinks(RvGraphNodeIter i)
{
	return rvListSize(&rvListIterData(i)->in);
}

RvBool rvGraphForEachNode(RvGraph *graph, RvGraphNodeFunc f, void *data)
{
	RvGraphNodeIter i , nextIter;
	for(i=rvGraphBegin(graph); i!=rvGraphEnd(graph); i=nextIter) {
		nextIter = rvGraphNodeIterNext(i);
		if(f(rvGraphNodeIterGetNode(i), data))
			return rvTrue;
	}
	return rvFalse;
}

RvBool rvGraphForEachLink(RvGraph *graph, RvGraphLinkFunc f, void *data)
{
	RvGraphNodeIter nodeIter,nextIter;
	for(nodeIter=rvGraphBegin(graph); nodeIter!=rvGraphEnd(graph); nodeIter=nextIter)
	{
		RvGraphLinkIter link,nextLink;
		nextIter = rvGraphNodeIterNext(nodeIter);
		for(link=rvGraphNodeOutLinksBegin(nodeIter);
		    link!=rvGraphNodeOutLinksEnd(nodeIter);
			link=nextLink)
		{
			nextLink = rvGraphLinkIterNext(link);
			if(f(rvGraphNodeIterGetNode(nodeIter), rvGraphLinkIterGetNode(link),
				rvGraphLinkIterGetData(link), data))
				return rvTrue;
		}
	}
	return rvFalse;
}

RvBool rvGraphForEachLinkFromNode(RvGraph *graph, void *node, RvGraphLinkFunc f, void *data)
{
	RvGraphNodeIter nodeIter = rvGraphFindNode(graph, node);
	if(nodeIter != rvGraphEnd(graph))
	{
		RvGraphLinkIter link,nextLink;
		for(link=rvGraphNodeOutLinksBegin(nodeIter);
		    link!=rvGraphNodeOutLinksEnd(nodeIter);
			link=nextLink)
		{
			nextLink = rvGraphLinkIterNext(link);
			if(f(rvGraphNodeIterGetNode(nodeIter), rvGraphLinkIterGetNode(link),
				rvGraphLinkIterGetData(link), data))
				return rvTrue;
		}
	}
	return rvFalse;
}

/* The function is always called in the order: head, tail */
RvBool rvGraphForEachLinkToNode(RvGraph *graph, void *node, RvGraphLinkFunc f, void *data)
{
	RvGraphNodeIter nodeIter = rvGraphFindNode(graph, node);
	if(nodeIter != rvGraphEnd(graph))
	{
		RvGraphLinkIter link,nextLink;
		for(link=rvGraphNodeInLinksBegin(nodeIter);
		    link!=rvGraphNodeInLinksEnd(nodeIter);
			link=nextLink)
		{
			nextLink = rvGraphLinkIterNext(link);
			if(f(rvGraphLinkIterGetNode(link),rvGraphNodeIterGetNode(nodeIter), 
				rvGraphLinkIterGetData(link), data))
				return rvTrue;
		}
	}
	return rvFalse;
}

void * rvGraphFindLinkFromNodeIter(RvGraph *graph, RvGraphNodeIter nodeIter,RvGraphNodeIter tailIter,RvGraphLinkCmpFunc f, void *data) {
/* 	void * node = rvGraphNodeIterGetNode(nodeIter); */
	if(nodeIter != rvGraphEnd(graph))
	{
		RvGraphLinkIter link;
		for(link=rvGraphNodeOutLinksBegin(nodeIter);
		    link!=rvGraphNodeOutLinksEnd(nodeIter);
			link=rvGraphLinkIterNext(link))
		{
			void * tail = rvGraphNodeIterGetNode(tailIter);
			if(rvGraphLinkIterGetNode(link)==tail && f(rvGraphLinkIterGetData(link),data) == rvTrue) 
				return rvGraphLinkIterGetData(link);
		}
	}
	return NULL;
}


void * rvGraphFindLinkFromNode(RvGraph *graph, void *node,void * tail,RvGraphLinkCmpFunc f, void *data) {
	return rvGraphFindLinkFromNodeIter(graph,rvGraphFindNode(graph,node),rvGraphFindNode(graph,tail),f,data);
}

void * rvGraphFindLinkToNode(RvGraph *graph, RvGraphNodeIter nodeIter,RvGraphNodeIter headIter,RvGraphLinkCmpFunc f, void *data) {
/*	void * node = rvGraphNodeIterGetNode(nodeIter); */
	if(nodeIter != rvGraphEnd(graph))
	{
		RvGraphLinkIter link;
		for(link=rvGraphNodeInLinksBegin(nodeIter);
		    link!=rvGraphNodeInLinksEnd(nodeIter);
			link=rvGraphLinkIterNext(link))
		{
			void * head = rvGraphNodeIterGetNode(headIter);
			if(rvGraphLinkIterGetNode(link)==head && f(rvGraphLinkIterGetData(link),data) == rvTrue) 
				return rvGraphLinkIterGetData(link);
		}
	}
	return NULL;
}

RvAlloc *rvGraphGetAllocator(const RvGraph *graph)
{
	return rvListGetAllocator(&graph->nodes);
}

⌨️ 快捷键说明

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