Exemplo n.º 1
0
static int	wipeList(const char *fileName, int lineNbr,
			PsmPartition partition, PsmAddress list,
			SmListDeleteFn deleteFn, void *arg, int destroy)
{
	SmList		*listBuffer;
	PsmAddress	elt;
	PsmAddress	next;
	SmListElt	*eltBuffer;

	listBuffer = (SmList *) psp(partition, list);
	if (lockSmlist(listBuffer) < 0)
	{
		putErrmsg(_cannotLockMsg(), NULL);
		return -1;
	}

	for (elt = listBuffer->first; elt != 0; elt = next)
	{
		eltBuffer = (SmListElt *) psp(partition, elt);
		CHKERR(eltBuffer);
		next = eltBuffer->next;
		if (deleteFn)
		{
			deleteFn(partition, elt, arg);
		}

		/* clear in case user mistakenly accesses later... */
		eraseListElt(eltBuffer);
		Psm_free(fileName, lineNbr, partition, elt);
	}

	eraseList(listBuffer);
	if (destroy)
	{
		sm_SemDelete(listBuffer->lock);
		listBuffer->lock = SM_SEM_NONE;
		Psm_free(fileName, lineNbr, partition, list);
	}
	else
	{
		unlockSmlist(listBuffer);
	}

	return 0;
}
Exemplo n.º 2
0
void	releaseToIonMemory(char *fileName, int lineNbr, void *block)
{
	PsmPartition	ionwm = _ionwm(NULL);

	Psm_free(fileName, lineNbr, ionwm, psa(ionwm, (char *) block));
#ifdef HAVE_VALGRIND_VALGRIND_H
    VALGRIND_FREELIKE_BLOCK(block, 0);
#endif
}
Exemplo n.º 3
0
void	Sm_rbt_destroy(char *file, int line, PsmPartition partition,
		PsmAddress rbt, SmRbtDeleteFn deleteFn, void *arg)
{
	SmRbt	*rbtPtr;

	CHKVOID(partition);
	CHKVOID(rbt);
	rbtPtr = (SmRbt *) psp(partition, rbt);
	oK(lockSmrbt(rbtPtr));
	destroyRbtNodes(file, line, partition, rbtPtr, deleteFn, arg);

	/*	Now destroy the tree itself.				*/

	sm_SemDelete(rbtPtr->lock);

	/*	just in case user mistakenly accesses later...		*/
	eraseTree(rbtPtr);
	Psm_free(file, line, partition, rbt);
}
Exemplo n.º 4
0
Arquivo: ion.c Projeto: b/ION
void	releaseToIonMemory(char *fileName, int lineNbr, void *block)
{
	PsmPartition	ionwm = _ionwm(NULL);

	Psm_free(fileName, lineNbr, ionwm, psa(ionwm, (char *) block));
}
Exemplo n.º 5
0
static void	releaseToDgrMemory(const char *fileName, int lineNbr,
			void *block)
{
	Psm_free(fileName, lineNbr, dgrwm, psa(dgrwm, (char *) block));
}
Exemplo n.º 6
0
void	Sm_rbt_delete(char *file, int line, PsmPartition partition,
		PsmAddress rbt, SmRbtCompareFn compare, void *dataBuffer,
		SmRbtDeleteFn deleteFn, void *arg)
{
	SmRbtNode	dummyRootBuffer = { 0, 0, {0, 0}, 0, 0 };
				/*	Dummy root is a trick; it
				 *	lets us avoid special cases.	*/
	SmRbt		*rbtPtr;
	PsmAddress	node;			//	q
	SmRbtNode	*nodePtr;		//	q
	PsmAddress	sibling;		//	s
	SmRbtNode	*siblingPtr;		//	s
	PsmAddress	parent;			//	p
	SmRbtNode	*parentPtr;		//	p
	PsmAddress	stepparent;		//	p
	SmRbtNode	*stepparentPtr;		//	p
	SmRbtNode	*grandparentPtr;	//	g
	PsmAddress	target;			//	f
	SmRbtNode	*targetPtr;		//	f
	int		direction;		//	dir
	int		otherDirection;		//	!dir
	int		prevDirection;		//	last
	int		prevOtherDirection;	//	!last
	int		subtree;		//	dir2
	SmRbtNode	*childPtr[2];
	int		result;
	int		i;
	int		j;

	CHKVOID(partition);
	CHKVOID(rbt);
	CHKVOID(compare);
	rbtPtr = (SmRbt *) psp(partition, rbt);
	CHKVOID(rbtPtr);
	if (rbtPtr->length == 0 || rbtPtr->root == 0
	|| lockSmrbt(rbtPtr) == ERROR)
	{
		return;
	}

	/*	We descend the tree, searching for the node that is
	 *	to be deleted (rather than requiring its address),
	 *	because we want to ensure that the node has been
	 *	recolored red -- if necessary -- by the time we
	 *	reach it.  This is because deleting a red node never
	 *	violates any red-black tree rules, so there is no
	 *	subsequent tree fix-up needed.  Our general strategy
	 *	is to push "red-ness" all the way down to the target
	 *	node, rotating as necessary to ensure that the target
	 *	node is transformed into a red leaf.
	 *
	 *	Note: a special case is when the node that is to be
	 *	deleted is the only node in the tree, hence the root.
	 *	In this case (only), we can delete a black node
	 *	without violating any red-black tree rules.
	 *
	 *	Note 2: this searching strategy is the reason we need
	 *	the compare function provided on node deletion just
	 *	as on node insertion.					*/

	grandparentPtr = NULL;
	parent = 0;				/*	None.		*/
	parentPtr = NULL;
	node = 0;
	nodePtr = &dummyRootBuffer;
	nodePtr->child[RIGHT] = rbtPtr->root;
	target = 0;				//	f
	direction = RIGHT;
	while (nodePtr->child[direction])
	{
		prevDirection = direction;
		grandparentPtr = parentPtr;

		/*	The first time through the loop, parentPtr
		 *	is NULL so grandparentPtr is still NULL.  The
		 *	second time through the loop, nodePtr is a
		 *	pointer to the dummy root, so the dummy root
		 *	becomes the grandparent.  The third time, a
		 *	pointer to the tree's root (a real node) is
		 *	placed in grandparentPtr.			*/

		parent = node;
		parentPtr = nodePtr;

		/*	The first time through the loop, nodePtr is
		 *	a pointer to the dummy root, so the dummy root
		 *	becomes the parent.  The second time, a pointer
		 *	to the tree's root (a real node) is placed in
		 *	parentPtr.					*/

		node = nodePtr->child[direction];
		nodePtr = (SmRbtNode *) psp(partition, node);

		/*	The first time through the loop, a pointer
		 *	to the tree's root (a real node) is placed in
		 *	nodePtr before any other processing happens.
		 *
		 *	Note that the loop continues PAST the node
		 *	that is to be deleted, locating that node's
		 *	inorder predecessor.  Then we come back to
		 *	move the predecessor's data into the target
		 *	node (erasing the target node's data) and
		 *	destroy to predecessor node.			*/

		result = compare(partition, nodePtr->data, dataBuffer);
		if (result < 0)
		{
			direction = RIGHT;
		}
		else
		{
			direction = LEFT;
			if (result == 0)
			{
				target = node;
			}
		}
 
 		if (nodeIsRed(partition, node)
		|| nodeIsRed(partition, nodePtr->child[direction]))
		{
			continue;	/*	No recolor needed.	*/
		}

		/*	Neither the node nor its child (if any) in
		 *	the current direction of search are red, so
		 *	we must introduce some redness.			*/

		otherDirection = 1 - direction;
		if (nodeIsRed(partition, nodePtr->child[otherDirection]))
		{
			/*	This is the "red sibling" case.  Rotate
			 *	current node down/red.			*/

			childPtr[otherDirection] = (SmRbtNode *)
				psp(partition, nodePtr->child[otherDirection]);
			parentPtr->child[prevDirection] =
				rotateOnce(partition, node, direction);

			/*	The new root of the subtree whose root
			 *	before rotation was "node" [the red
			 *	sibling] must be noted as "parent" in
			 *	place of the original parent of "node",
			 *	because it is now the actual parent
			 *	of "node".				*/

			parent = parentPtr->child[prevDirection];
			parentPtr = (SmRbtNode *) psp(partition, parent);

			/*	We've introduced the necessary redness;
			 *	time to descend again.			*/

			continue;
		}

		/*	Node and all of its children (if any) are now
		 *	known to be black.
		 *
		 *	Remaining cases concern the children (if any)
		 *	of the sibling (if any) of the current node.	*/

		prevOtherDirection = 1 - prevDirection;
		sibling = parentPtr->child[prevOtherDirection];
		if (sibling == 0)	/*	(True of tree root.)	*/
		{
			continue;	/*	No sibling, no problem.	*/
		}

		/*	Node has got a sibling.  Therefore it can't be
		 *	the root of the tree, so the root of the tree
		 *	must be above this node.  Therefore this node's
		 *	parent cannot be the dummy node, so both the
		 *	node's parent and the dummy node are above this
		 *	node in the tree.  So the node must have a
		 *	grandparent (the dummy node or some real node
		 *	lower in the tree).  So grandparentPtr cannot
		 *	be NULL.					*/

		siblingPtr = (SmRbtNode *) psp(partition, sibling);

		/*	Check for need to flip colors.  NOT TREE ROOT.	*/

		if (nodeIsRed(partition, siblingPtr->child[LEFT]) == 0
		&& nodeIsRed(partition, siblingPtr->child[RIGHT]) == 0)
		{
			/*	Sibling has no red children, so it's
			 *	safe to make both the current node and
			 *	its sibling RED and their parent BLACK.	*/

			parentPtr->isRed = 0;
			siblingPtr->isRed = 1;
			nodePtr->isRed = 1;
			continue;
		}

		if (parent == grandparentPtr->child[RIGHT])
		{
			subtree = RIGHT;
		}
		else
		{
			subtree = LEFT;
		}

		/*	Note: grandparent is known to have a child
		 *	on the "subtree" side ("parent"), even if
		 *	grandparent is dummy.  And that child is
		 *	known to have two children -- "node" and
		 *	"sibling".					*/

		if (nodeIsRed(partition, siblingPtr->child[prevDirection]))
		{
			grandparentPtr->child[subtree] =
				rotateTwice(partition, parent, prevDirection);
		}
		else
		{
			if (nodeIsRed(partition,
					siblingPtr->child[prevOtherDirection]))
			{
				grandparentPtr->child[subtree] =
				rotateOnce(partition, parent, prevDirection);
			}
		}

		/*	The subtree may now have a new parent, due
		 *	to rotation.  Ensure nodes have correct colors.	*/

		stepparent = grandparentPtr->child[subtree];
		stepparentPtr = (SmRbtNode *) psp(partition, stepparent);
		stepparentPtr->isRed = 1;
		nodePtr->isRed = 1;
		childPtr[LEFT] = (SmRbtNode *) psp(partition,
				stepparentPtr->child[LEFT]);
		childPtr[LEFT]->isRed = 0;
		childPtr[RIGHT] = (SmRbtNode *) psp(partition,
				stepparentPtr->child[RIGHT]);
		childPtr[RIGHT]->isRed = 0;
	}
 
	/*	At this point the current node is NOT the one we're
	 *	trying to delete.  It is the inorder predecessor of
	 *	the node we're trying to delete -- a node whose
	 *	content we want to retain.  The data that's in this
	 *	predecessor is retained by copying it into the 
	 *	target node -- which effectively deletes the target
	 *	node without actually removing it from the tree.
	 *	Then the current node (the inorder predecessor of
	 *	the target node, which is now redundant) is removed
	 *	from the tree.						*/

	if (target)
	{
		targetPtr = (SmRbtNode *) psp(partition, target);
		if (deleteFn)
		{
			deleteFn(partition, targetPtr->data, arg);
		}

		targetPtr->data = nodePtr->data;

		/*	To destroy inorder predecessor node, must
		 *	make its parent forget about it.		*/

		if (parentPtr->child[RIGHT] == node)
		{
			i = RIGHT;
		}
		else
		{
			i = LEFT;
		}

		if (nodePtr->child[LEFT] == 0)
		{
			j = RIGHT;
		}
		else
		{
			j = LEFT;
		}

		parentPtr->child[i] = nodePtr->child[j];

		/*	just in case user mistakenly accesses later...	*/
		eraseTreeNode(nodePtr);
		Psm_free(file, line, partition, node);
		rbtPtr->length -= 1;
	}

	/*	Update root in rbt object.				*/
 
	rbtPtr->root = dummyRootBuffer.child[RIGHT];

	/*	Make sure root is BLACK.				*/

	if (rbtPtr->root)
	{
		nodePtr = (SmRbtNode *) psp(partition, rbtPtr->root);
		nodePtr->isRed = 0;
	}

	unlockSmrbt(rbtPtr);
}
Exemplo n.º 7
0
static void	destroyRbtNodes(char *file, int line, PsmPartition partition,
			SmRbt *rbtPtr, SmRbtDeleteFn deleteFn, void *arg)
{
	PsmAddress	node;
	SmRbtNode	*nodePtr;
	PsmAddress	parentNode;

	node = rbtPtr->root;
	nodePtr = (SmRbtNode *) psp(partition, node);

	/*	Destroy all nodes of the tree.				*/

	while (node)
	{
		/*	If node has a left subtree, descend into it.	*/

		if (nodePtr->child[LEFT])
		{
			node = nodePtr->child[LEFT];
			nodePtr = (SmRbtNode *) psp(partition, node);
			continue;
		}

		/*	If node has a right subtree, descend into it.	*/

		if (nodePtr->child[RIGHT])
		{
			node = nodePtr->child[RIGHT];
			nodePtr = (SmRbtNode *) psp(partition, node);
			continue;
		}

		/*	Node is a leaf, so can delete it.		*/

		parentNode = nodePtr->parent;
		if (deleteFn)
		{
			deleteFn(partition, nodePtr->data, arg);
		}

		/*	just in case user mistakenly accesses later...	*/
		eraseTreeNode(nodePtr);
		Psm_free(file, line, partition, node);

		/*	Now pop back up to this node's parent.		*/

		if (parentNode == 0)
		{
			rbtPtr->root = 0;
			break;	/*	Have deleted the root node.	*/
		}

		nodePtr = (SmRbtNode *) psp(partition, parentNode);

		/*	Erase the child pointer for the child that
		 *	has now been deleted.				*/

		if (node == nodePtr->child[LEFT])
		{
			nodePtr->child[LEFT] = 0;
		}

		if (node == nodePtr->child[RIGHT])
		{
			nodePtr->child[RIGHT] = 0;
		}

		node = parentNode;
	}
}
Exemplo n.º 8
0
int	Sm_list_delete(const char *fileName, int lineNbr,
		PsmPartition partition, PsmAddress elt, SmListDeleteFn deleteFn,
		void *arg)
{
	SmListElt	*eltBuffer;
	PsmAddress	list;
	SmList		*listBuffer;
	PsmAddress	next;
	PsmAddress	prev;

	CHKERR(partition);
	CHKERR(elt);
	eltBuffer = (SmListElt *) psp(partition, elt);
	CHKERR(eltBuffer);
	if ((list = eltBuffer->list) == 0)
	{
		putErrmsg(_noListMsg(), NULL);
		return -1;
	}

	listBuffer = (SmList *) psp(partition, list);
	if (lockSmlist(listBuffer) == ERROR)
	{
		putErrmsg(_cannotLockMsg(), NULL);
		return -1;
	}

	if (listBuffer->length < 1)
	{
		unlockSmlist(listBuffer);
		putErrmsg("list element can't be deleted, list is empty", NULL);
		return -1;
	}

	next = eltBuffer->next;
	prev = eltBuffer->prev;
	if (deleteFn)
	{
		deleteFn(partition, elt, arg);
	}

	/* clear in case user accesses later... */
	eraseListElt(eltBuffer);
	Psm_free(fileName, lineNbr, partition, elt);
	if (prev)
	{
		eltBuffer = (SmListElt *) psp(partition, prev);
		CHKERR(eltBuffer);
		eltBuffer->next = next;
	}
	else
	{
		listBuffer->first = next;
	}

	if (next)
	{
		eltBuffer = (SmListElt *) psp(partition, next);
		CHKERR(eltBuffer);
		eltBuffer->prev = prev;
	}
	else
	{
		listBuffer->last = prev;
	}

	listBuffer->length -= 1;
	unlockSmlist(listBuffer);
	return 0;
}
Exemplo n.º 9
0
void		Sdr_free(const char *file, int line,
				Sdr sdr, Object object)
{
	//TODO check sdr type
	return Psm_free(file, line, sdr, object);
}