/* --------------------------------------------------------------------------------- * LQuickFind_Find * --------------------------------------------------------------------------------- * Find */ ui4 LQuickFind_Find (LQuickFind* This, ui4 inItem) { LArray *thelarray; #if LQuickFind_STATS /*updates stats...*/ This->mNumFinds++; #endif /*parameter checking...*/ if (inItem==LQuickFind_BAD_ITEM) return LQuickFind_BAD_ITEM; /*if not found...*/ //if (!LHash_IsInTable (This->mHashTable, inItem)) //return LQuickFind_BAD_ITEM; /*not a valid node id...*/ /*retrieves tree (LArray) from node id...*/ thelarray=(LArray *)LHash_GetItemByKey (This->mHashTable, inItem); /*if not found...*/ if (thelarray==NULL) return LQuickFind_BAD_ITEM; /*returns node id...*/ return *((ui4 *)LArray_ItemAt (thelarray, 0)); }
ui4 LArray_AppendUniqueItem(LArray* This, const void* inItem){ ui4 i; for (i = 0; i < LArray_GetItemsCount(This); i++) { if (!LMemory_Compare(inItem, LArray_ItemAt(This, i), This->mItemSize)) return i; } return LArray_AppendItem(This, inItem); }
/* --------------------------------------------------------------------------------- * LQuickFind_GetUsedMem * --------------------------------------------------------------------------------- * GetUsedMem */ ui4 LQuickFind_GetUsedMem (LQuickFind* This) { ui4 theHashTableUsedMem=0; ui4 theQuickFindStructUsedMem=0; ui4 theLArraysUsedMem=0; LArray* theItems; ui4 theNumItems; LArray** theTreePtr; ui4 i; LHash* theTmpHashTable; /*creates tmp hash table...*/ theTmpHashTable=LHash_New (); /*size of hash table...*/ theHashTableUsedMem=LHash_GetUsedMem (This->mHashTable); /*size of struct LQuickFind...*/ theQuickFindStructUsedMem=sizeof (struct LQuickFind); /*size of all larrays...*/ theItems=LHash_GetAllItems (This->mHashTable); theNumItems=LArray_GetItemsCount (theItems); for (i=0; i<theNumItems; i++) { /*retrieves pointer to tree...*/ theTreePtr=(LArray **)LArray_ItemAt (theItems, i); /*if not in tmp hash table...*/ if (!LHash_IsInTable (theTmpHashTable, (ui4)*theTreePtr)) { /*insert in tmp hash table...*/ LHash_InsertItem (theTmpHashTable, NULL, (ui4)*theTreePtr); /*take size into account...*/ theLArraysUsedMem=theLArraysUsedMem + LArray_GetUsedMem(*theTreePtr); } } /*deletes tmp hash table...*/ LHash_Delete (&theTmpHashTable); /*must be manually deleted...*/ LArray_Delete (&theItems); return (theHashTableUsedMem + theQuickFindStructUsedMem + theLArraysUsedMem); }
void LQuickFind_Delete (LQuickFind** ThisA) { LArray* theItems; ui4 theNumItems; ui4 i; LArray** theTreePtr; LHash* theTmpHashTable; /*creates tmp hash table...*/ theTmpHashTable=LHash_New (); /*retrieves pointers to all trees (larrays)...*/ theItems=LHash_GetAllItems ((*ThisA)->mHashTable); /*deletes all larrays...*/ theNumItems=LArray_GetItemsCount (theItems); for (i=0; i<theNumItems; i++) { /*retrieves pointer to tree...*/ theTreePtr=(LArray **)LArray_ItemAt (theItems, i); /*if not in tmp hash table...*/ if (!LHash_IsInTable (theTmpHashTable, (ui4)*theTreePtr)) { /*insert in tmp hash table...*/ LHash_InsertItem (theTmpHashTable, NULL, (ui4)*theTreePtr); /*delete tree...*/ LArray_Delete (theTreePtr); } } /*deletes tmp hash table...*/ LHash_Delete (&theTmpHashTable); /*must be manually deleted...*/ LArray_Delete (&theItems); /*deletes hash table...*/ LHash_Delete (&((*ThisA)->mHashTable)); /*deletes object...*/ LMemory_DeleteObject (ThisA); }
/* --------------------------------------------------------------------------------- * _LEdgeInfo_DeleteItemAt * --------------------------------------------------------------------------------- * Delete the info of a specified Edge*/ void _LEdgeInfo_DeleteItemAt(LEdgeInfo* This, LGraph_TEdge* inEdge) { LException* theException; ui4 theIndex; if (This == NULL) Throw(LEdgeInfo_OBJECT_NULL_POINTER); /* if installed, calls the destructor handler */ if (This->mDealloc) (*(This->mDealloc))(This, inEdge); theIndex = inEdge->mIndex; LMemory_Copy(LArray_LastItem(This->mData), LArray_ItemAt(This->mData, theIndex), LArray_GetItemSize(This->mData)); Try LArray_ResizeBy(This->mData, -1); Catch(theException) LException_Dump(theException); }
/* --------------------------------------------------------------------------------- * LEdgeInfo_AssignItemAt * --------------------------------------------------------------------------------- * Assigns the data pointed by inItem to the Edge inEdge */ void LEdgeInfo_AssignItemAt(LEdgeInfo* This, LGraph_TEdge* inEdge, const void* inItem) { /*at this point there MUST be the allocated space for the item */ LException* theException; void* thePtr; ui4 theItemSize; if (This == NULL) Throw(LEdgeInfo_OBJECT_NULL_POINTER); if (inEdge == NULL) Throw(LEdgeInfo_EDGE_NULL_POINTER); if (inItem == NULL) Throw(LEdgeInfo_ITEM_NULL_POINTER); Try { thePtr = LArray_ItemAt(This->mData, inEdge->mIndex); theItemSize = LArray_GetItemSize(This->mData); } Catch(theException) LException_Dump(theException); LMemory_Copy(inItem, thePtr, theItemSize); }
/* --------------------------------------------------------------------------------- * LQuickFind_Union * --------------------------------------------------------------------------------- * Union */ ui4 LQuickFind_Union (LQuickFind* This, ui4 inItem1, ui4 inItem2) { ui4 thelength1, thelength2; LArray *thelarray1, *thelarray2; ui4 i; ui4 *thecur_item; ui4 theset1, theset2; void *theSource, *theDest; #if LQuickFind_STATS /*updates stats...*/ This->mNumUnions++; #endif /*parameter checking...*/ if ((inItem1==LQuickFind_BAD_ITEM) || (inItem2==LQuickFind_BAD_ITEM)) return LQuickFind_BAD_ITEM; theset1=LQuickFind_Find (This, inItem1); theset2=LQuickFind_Find (This, inItem2); /*if either set doesn't exist...*/ if ((theset1==LQuickFind_BAD_ITEM) || (theset2==LQuickFind_BAD_ITEM)) return LQuickFind_BAD_ITEM; /*returns an invalid id...*/ /*if already in same set...*/ if (theset1==theset2) return theset1; //nothing to do... /*retrieves 1st tree (LArray)...*/ thelarray1=(LArray *)LHash_GetItemByKey (This->mHashTable, inItem1); /*retrieves 2nd tree (LArray)...*/ thelarray2=(LArray *)LHash_GetItemByKey (This->mHashTable, inItem2); /*gets lengths...*/ thelength1=LArray_GetItemsCount (thelarray1); thelength2=LArray_GetItemsCount (thelarray2); /*performs (balanced) union...*/ if (thelength1 >= thelength2) { /*resizes larray1...*/ LArray_ResizeBy (thelarray1, thelength2); /*gets address of first item of larray2...*/ theSource=LArray_ItemAt (thelarray2, 0); /*gets first empty slot in larray1...*/ theDest=LArray_ItemAt (thelarray1, thelength1); /*copies larray2 onto larray1...*/ LMemory_Copy (theSource, theDest, thelength2*4); #if LQuickFind_STATS /*updates stats...*/ This->mItemsMovedByUnions=This->mItemsMovedByUnions+thelength2; #endif for (i=0; i<thelength2; i++) { thecur_item=(ui4 *)LArray_ItemAt (thelarray2, i); //LArray_AppendItem (thelarray1, thecur_item); /*replaces item in hash table...*/ //LHash_InsertItem (This->mHashTable, (void *)thelarray1, *thecur_item); LHash_ReplaceItemByKey (This->mHashTable, *thecur_item, (void *)thelarray1); } LArray_Delete (&thelarray2); } else { /*renames tree as well...*/ thecur_item=(ui4 *)LArray_ItemAt (thelarray1, 0); LArray_InsertItemAt (thelarray2, thecur_item, 0); /*replaces item in hash table...*/ LHash_InsertItem (This->mHashTable, (void *)thelarray2, *thecur_item); if (thelength1>1) { /*resizes larray2...*/ LArray_ResizeBy (thelarray2, thelength1-1); /*gets address of second item of larray1...*/ theSource=LArray_ItemAt (thelarray1, 1); /*gets first empty slot in larray1...*/ theDest=LArray_ItemAt (thelarray2, thelength2+1); /*copies larray1 onto larray2...*/ LMemory_Copy (theSource, theDest, (thelength1-1)*4); } #if LQuickFind_STATS /*updates stats...*/ This->mItemsMovedByUnions=This->mItemsMovedByUnions+thelength1; #endif for (i=1; i<thelength1; i++) { thecur_item=(ui4 *)LArray_ItemAt (thelarray1, i); //LArray_AppendItem (thelarray2, thecur_item); /*replaces item in hash table...*/ //LHash_InsertItem (This->mHashTable, (void *)thelarray2, *thecur_item); LHash_ReplaceItemByKey (This->mHashTable, *thecur_item, (void *)thelarray2); } LArray_Delete (&thelarray1); } /*returns appropriate set name...*/ if (thelength1 >= thelength2) return theset1; else return theset2; }