Example #1
0
long CMuleListCtrl::GetInsertPos(wxUIntPtr data)
{
	// Find the best place to position the item through a binary search
	int Min = 0;
	int Max = GetItemCount();

	// Only do this if there are any items and a sorter function.
	// Otherwise insert at end.
	if (Max && m_sort_func) {
		// This search will find the place to position the new item
		// so it matches current sorting.
		// The result will be the position the new item will have
		// after insertion, which is the format expected by the InsertItem function.
		// If the item equals another item it will be inserted after it.
		do {
			int cur_pos = ( Max - Min ) / 2 + Min;
			int cmp = CompareItems(data, GetItemData(cur_pos));
			
			// Value is less than the one at the current pos
			if ( cmp < 0 ) {
				Max = cur_pos;
			} else {
				Min = cur_pos + 1;
			}			
		} while ((Min != Max));
	}

	return Max;
}
Example #2
0
bool CMuleListCtrl::IsItemSorted(long item)
{
	wxCHECK_MSG(m_sort_func, true, wxT("No sort function specified!"));
	wxCHECK_MSG((item >= 0) && (item < GetItemCount()), true, wxT("Invalid item"));
	
	bool sorted = true;
	wxUIntPtr data = GetItemData(item);

	// Check that the item before the current item is smaller (or equal)
	if (item > 0) {
		sorted &= (CompareItems(GetItemData(item - 1), data) <= 0);
	}

	// Check that the item after the current item is greater (or equal)
	if (sorted && (item < GetItemCount() - 1)) {
		sorted &= (CompareItems(GetItemData(item + 1), data) >= 0);
	}

	return sorted;
}
Example #3
0
void CIniEx::QuickSortRecursive(int nSection, int iLow, int iHigh, bool bAscending)
{
	// Params renamed for easier comparison with literature
	int iLeft = iLow;
	int iRight = iHigh;

	// Important: Save Pivot-Element on Stack, instead of using GetAt(iPivot) in 
	// "while('compare')-Loop". Original implementation by Attila Hajdrik used 
	// GetAt(iPivot) in within the Loop
	// int iPivot = (iLow+iHigh) / 2;
	CString Pivot = m_Keys[nSection]->GetAt((iLow+iHigh) / 2); 

	do
	{
		if( bAscending )
		{
			while( CompareItems(m_Keys[nSection]->GetAt(iLeft), Pivot) < 0 ) iLeft++;
			while( CompareItems(Pivot, m_Keys[nSection]->GetAt(iRight)) < 0 ) iRight--;
		}
		else
		{
			while( CompareItems(m_Keys[nSection]->GetAt(iLeft), Pivot) > 0 ) iLeft++;
			while( CompareItems(Pivot, m_Keys[nSection]->GetAt(iRight)) > 0 ) iRight--;
		}

		if( iLeft <= iRight )
		{
			Swap(nSection, iLeft, iRight);

			iLeft++;
			iRight--;
		}
	}
	while( iLeft <= iRight );

	if( iLow < iRight )
		QuickSortRecursive(nSection, iLow, iRight, bAscending);

	if( iLeft < iHigh )
		QuickSortRecursive(nSection, iLeft, iHigh, bAscending);
}
int isNeedNewUnit(int id, pItem ilist)
{
    if(id < 1  || ! ilist) {
        debug("parameter error");
        return ERR;
    }

    const pItem curent  = (const pItem)&ilist[id];
    const pItem prev    = (const pItem)&ilist[id-1];
    if(prev->len==0) return 0;
    return CompareItems(curent,prev);
}
Example #5
0
// Check two item set lists for equality
int CompareItemSets(LR_ITEM_SET* one, LR_ITEM_SET* two)
{
    while (one && two)
    {
        if (CompareItems(one->item, two->item) != 0)
            return 1;
        one = one->next;
        two = two->next;
    }
    
    if (one || two)
        return 1;
    return 0;
}
Example #6
0
bool CIniEx::Swap( int nSection, int nLeftIndex, int nRightIndex )
{
	// Ignore unnecessary swaps
	if( nLeftIndex == nRightIndex ) return false;
	if( nRightIndex == (nLeftIndex + 1) && CompareItems(m_Keys[nSection]->GetAt(nLeftIndex), m_Keys[nSection]->GetAt(nRightIndex)) == 0 ) return false;

	CString strHelp = m_Keys[nSection]->GetAt(nLeftIndex);
	m_Keys[nSection]->SetAt(nLeftIndex, m_Keys[nSection]->GetAt(nRightIndex) );
	m_Keys[nSection]->SetAt(nRightIndex, strHelp );

	strHelp = m_Values[nSection]->GetAt(nLeftIndex);
	m_Values[nSection]->SetAt(nLeftIndex, m_Values[nSection]->GetAt(nRightIndex));
	m_Values[nSection]->SetAt(nRightIndex, strHelp);

	return true;
}
Example #7
0
// Simple parallel quick-sort.  "first" and "last" are the first
// and last items (inclusive) in the vector.
void DepthVector::SortRange(Item *first, Item *last)
{
    while (first < last)
    {
        if (last-first <= 100)
        {
            // Use the standard library function for small ranges.
            qsort(first, last-first+1, sizeof(Item), qsCompare);
            return;
        }
        // Select the best pivot from the first, last and middle item
        // by sorting these three items.  We use the middle item as
        // the pivot and since the first and last items are sorted
        // by this we can skip them when we start the partitioning.
        Item *middle = first + (last-first)/2;
        if (CompareItems(first, middle) > 0)
            swapItems(first, middle);
        if (CompareItems(middle, last) > 0)
        {
            swapItems(middle, last);
            if (CompareItems(first, middle) > 0)
                swapItems(first, middle);
        }

        // Partition the data about the pivot.  This divides the
        // vector into two partitions with all items <= pivot to
        // the left and all items >= pivot to the right.
        // Note: items equal to the pivot could be in either partition.
        Item *f = first+1;
        Item *l = last-1;

        do {
            // Find an item we have to move.  These loops will always
            // terminate because testing the middle with itself
            // will return == 0.
            while (CompareItems(f, middle/* pivot*/) < 0)
                f++;
            while (CompareItems(middle/* pivot*/, l) < 0)
                l--;
            // If we haven't finished we need to swap the items.
            if (f < l)
            {
                swapItems(f, l);
                // If one of these was the pivot item it will have moved to
                // the other position.
                if (middle == f)
                    middle = l;
                else if (middle == l)
                    middle = f;
                f++;
                l--;
            }
            else if (f == l)
            {
                f++;
                l--;
                break;
            }
        } while (f <= l);

        // Process the larger partition as a separate task or
        // by recursion and do the smaller partition by tail
        // recursion.
        if (l-first > last-f)
        {
            // Lower part is larger
            gpTaskFarm->AddWorkOrRunNow(sortTask, first, l);
            first = f;
        }
        else
        {
            // Upper part is larger
            gpTaskFarm->AddWorkOrRunNow(sortTask, f, last);
            last = l;
        }
    }
}
Example #8
0
// Merge cells with the same contents.
POLYUNSIGNED DepthVector::MergeSameItems()
{
    DepthVector *v = this;

    POLYUNSIGNED  N = v->nitems;
    Item *itemVec = v->vector;
    POLYUNSIGNED  n = 0;
    POLYUNSIGNED  i = 0;

    while (i < N)
    {
        PolyObject *bestShare = 0; // Candidate to share.
        MemSpace *bestSpace = 0;

        POLYUNSIGNED j;
        for (j = i; j < N; j++)
        {
            ASSERT (OBJ_IS_DEPTH(itemVec[i].pt->LengthWord()));
            // Search for identical objects.  Don't bother to compare it with itself.
            if (i != j && CompareItems (& itemVec[i], & itemVec[j]) != 0) break;
            // The order of sharing is significant.
            // Choose an object in the permanent memory if that is available.
            // This is necessary to retain the invariant that no object in
            // the permanent memory points to an object in the temporary heap.
            // (There may well be pointers to this object elsewhere in the permanent
            // heap).
            // Choose the lowest hierarchy value for preference since that
            // may reduce the size of saved state when resaving already saved
            // data.
            // If we can't find a permanent space choose a space that isn't
            // an allocation space.  Otherwise we could break the invariant
            // that immutable areas never point into the allocation area.
            MemSpace *space = gMem.SpaceForAddress(itemVec[j].pt);
            if (bestSpace == 0)
            {
                bestShare = itemVec[j].pt;
                bestSpace = space;
            }
            else if (bestSpace->spaceType == ST_PERMANENT)
            {
                // Only update if the current space is also permanent and a lower hierarchy
                if (space->spaceType == ST_PERMANENT &&
                        ((PermanentMemSpace *)space)->hierarchy < ((PermanentMemSpace *)bestSpace)->hierarchy)
                {
                    bestShare = itemVec[j].pt;
                    bestSpace = space;
                }
            }
            else if (bestSpace->spaceType == ST_LOCAL)
            {
                // Update if the current space is not an allocation space
                if (space->spaceType != ST_LOCAL || ! ((LocalMemSpace*)space)->allocationSpace)
                {
                    bestShare = itemVec[j].pt;
                    bestSpace = space;
                }
            }
        }
        POLYUNSIGNED k = j; // Remember the first object that didn't match.
        //.For each identical object set all but the one we want to point to
        // the shared object.
        for (j = i; j < k; j++)
        {
            ASSERT (OBJ_IS_DEPTH(itemVec[j].pt->LengthWord()));
            if (itemVec[j].pt == bestShare)
            {
                // This is the common object.
                bestShare->SetLengthWord(itemVec[j].L); // restore genuine length word
                ASSERT (OBJ_IS_LENGTH(bestShare->LengthWord()));
            }
            else
            {
                itemVec[j].pt->SetForwardingPtr(bestShare); /* an indirection */
                ASSERT (itemVec[j].pt->ContainsForwardingPtr());
                n++;
            }
        }
        ASSERT(! OBJ_IS_DEPTH(itemVec[i].pt->LengthWord()));
        i = k;
    }

    return n;
}
Example #9
0
 static int qsCompare(const void *a, const void *b)
     { return CompareItems((const Item*)a, (const Item*)b); }
/**
 * Sort() performs a selection sort on list (it assumes list points to the head
 * of the list) to sort the elements into ascending order. It makes no
 * guarantees of the addresses of the list items after sorting, so any ListItem
 * referenced before a call to Sort() and after may contain different data. Its
 * second argument is a comparison function that calculates the ordering. This
 * function takes two const ListItem pointers and return 1 if the first one is
 * "larger", 0 if they're "equal", and -1 if the second one is "bigger". Since
 * sorting relies on understanding the data within the ListItem, the comparison
 * function is left up to the caller to define. This comparison function follows
 * the same return types as the one used for qsort(). See qsort()'s
 * documentation for further information. For consistency Sort() returns
 * SUCCESS if successful. There is no internal error checking and so will never
 * return anything else.
 */
int Sort(ListItem *list, int (*CompareItems)(const ListItem *, const ListItem *))
{
    /*
     * Declaring variables
     */
    list = GetFirst(list);
    int listPointerCount = 0;
    ListItem *listptr;
    listptr = (ListItem *) (malloc(sizeof (ListItem)));
    listptr = list->nextItem;
    /*
     * Counts the length of the stack and makes counter according
     * to the length
     */
    while (listptr->nextItem != NULL) {
	listPointerCount++;
	/*
	 * We do this several times where we compare based on value at
	 * the location of the pointer list. Depending on the value
	 * returned by compare, we may swap the two pointers.
	 */
	if (CompareItems(listptr, list) == TRUE) {
	    SwapData(list, listptr);
	    if (list->previousItem == NULL) {
		/*
		 * This increments until the counter is back to NULL.
		 * Essentially determines how far to go by counter.
		 */
		while (listPointerCount != NULL) {
		    listptr = listptr->nextItem;
		    list = list->nextItem;
		    listPointerCount--;
		}
		/*
		 * This continues the search if not a NULL
		 */
	    } else {
		listptr = listptr->previousItem;
		list = list->previousItem;
	    }
	    /*
	     * This checks to see if the pointers are the same. If they are
	     * then we do nothing just increment.
	     */
	} else {
	    if (list->previousItem == NULL) {
		while (listPointerCount != NULL) {
		    listptr = listptr->nextItem;
		    list = list->nextItem;
		    listPointerCount--;
		}
	    } else {
		listptr = listptr->previousItem;
		list = list->previousItem;
	    }
	}
    }
    /*
     * Repeat and step through the code (identical code)
     */
    while (TRUE) {
	if (CompareItems(listptr, list) == TRUE) {
	    SwapData(list, listptr);
	    if (list->previousItem == NULL) {
		listptr = listptr->nextItem;
		list = list->nextItem;
	    } else {
		listptr = listptr->previousItem;
		list = list->previousItem;
	    }
	} else {
	    if (list->previousItem == NULL) {
		listptr = listptr->nextItem;
		list = list->nextItem;
	    } else {
		listptr = listptr->previousItem;
		list = list->previousItem;
	    }
	}
	if (list->previousItem == NULL) {
	    if (CompareItems(listptr, list) == TRUE) {
		SwapData(list, listptr);
		return FALSE;
	    } else {
		return FALSE;
	    }
	}
    }
}
Example #11
0
File: sort.c Project: dnaeon/core
Rlist *SortRlist(Rlist *list, int (*CompareItems) ())
/*
 * Sorts an Rlist on list->item. A function CompareItems(i1,i2)
 * must be written for this particular item, which returns
 * true if i1 <= i2, false otherwise.
 *
 * after using this function passed parameter pointer will be lost
 * use returned pointer to access container
 */
{
    Rlist *p = NULL, *q = NULL, *e = NULL, *tail = NULL;
    int insize = 0, nmerges = 0, psize = 0, qsize = 0, i = 0;

    if (list == NULL)
    {
        return NULL;
    }

    insize = 1;

    while (true)
    {
        p = list;
        list = NULL;
        tail = NULL;

        nmerges = 0;            /* count number of merges we do in this pass */

        while (p)
        {
            nmerges++;          /* there exists a merge to be done */
            /* step `insize' places along from p */
            q = p;
            psize = 0;

            for (i = 0; i < insize; i++)
            {
                psize++;

                q = q->next;

                if (!q)
                {
                    break;
                }
            }

            /* if q hasn't fallen off end, we have two lists to merge */
            qsize = insize;

            /* now we have two lists; merge them */
            while (psize > 0 || (qsize > 0 && q))
            {
                /* decide whether next element of merge comes from p or q */
                if (psize == 0)
                {
                    /* p is empty; e must come from q. */
                    e = q;
                    q = q->next;
                    qsize--;
                }
                else if (qsize == 0 || !q)
                {
                    /* q is empty; e must come from p. */
                    e = p;
                    p = p->next;
                    psize--;
                }
                else if (CompareItems(p->item, q->item))
                {
                    /* First element of p is lower (or same);
                     * e must come from p. */
                    e = p;
                    p = p->next;
                    psize--;
                }
                else
                {
                    /* First element of q is lower; e must come from q. */
                    e = q;
                    q = q->next;
                    qsize--;
                }

                /* add the next element to the merged list */
                if (tail)
                {
                    tail->next = e;
                }
                else
                {
                    list = e;
                }

                tail = e;
            }

            /* now p has stepped `insize' places along, and q has too */
            p = q;
        }

        tail->next = NULL;

        /* If we have done only one merge, we're finished. */

        if (nmerges <= 1)       /* allow for nmerges==0, the empty list case */
        {
            return list;
        }

        /* Otherwise repeat, merging lists twice the size */
        insize *= 2;
    }

}
Example #12
0
/*
function closure(I):
begin
    repeat
        for each item [A -> a*ZB, a] in I,
            each production Z -> y in G',
            and each terminal b in FIRST(Ba)
            such that [Z -> *y, b] is not in I do
                add [Z -> *y, b] to I;
    until no more items can be added to I;
    return I
end;
*/
LR_ITEM_SET* Closure(LR_ITEM_SET* I, GRAMMAR_TABLE* G)
{
    // J := I;
    LR_ITEM_SET* J = CopyItemSet(I);

    // repeat
    int stillAdding;
    do {
        stillAdding = 0;

        // for each item [A -> a*ZB, a] in J,
        LR_ITEM_SET* itr;
        for (itr = J; itr; itr = itr->next)
        {
            LR_ITEM item = itr->item;
            RULE rule = G->rules[item.production];
            if (item.dot < rule.rhsLength)
            {
                int Z = rule.rhs[item.dot];
                // each production Z -> y in G',
                int i;
                for (i = 0; i < G->numRules; i++)
                {
                    if (G->rules[i].lhs == Z)
                    {
                        // and each terminal b in FIRST(Ba)
                        int B = (item.dot + 1 < rule.rhsLength) ?
                                        rule.rhs[item.dot + 1] : 0;
                        int b;
                        for (b = 0; b < G->numTokens; b++)
                        {
                            int terminal = (b + 1) | K_TOKEN;
                            if ((B && GetFirstTable(B, terminal, G) == 1) ||
                                ((!B || IsNullable(B)) &&
                                GetFirstTable(item.lookahead, terminal, G)
                                    == 1))
                            {
                                // such that [Z -> *y, b] is not in J do
                                LR_ITEM add;
                                add.production = i;
                                add.dot = 0;
                                add.lookahead = terminal;

                                LR_ITEM_SET* find;
                                for (find = J; find; find = find->next)
                                {
                                    if (CompareItems(find->item, add) == 0)
                                        break;
                                }

                                if (find == NULL)
                                {
                                    // add [Z -> *y, b] to J;
                                    find = malloc(sizeof(LR_ITEM_SET));
                                    find->item = add;
                                    find->next = J;
                                    J = find;
                                    stillAdding = 1;
                                }
                            }
                        }
                    }
                }
            }
        }
    // until no more items can be added to J;
    } while (stillAdding);

    // return J
    return Sort(J);
}
Example #13
0
// sort LR_ITEM_SET list for easy comparison
LR_ITEM_SET* Sort(LR_ITEM_SET* I)
{
    LR_ITEM_SET* itr;
    LR_ITEM* heap;
    int i, size;
    
    if (I == NULL) return I;
    
    // count elements [O(N)]
    size = 0;
    for (itr = I; itr; itr = itr->next)
    {
        size++;
    }
    
    // allocate heap [O(1)]
    heap = malloc(sizeof(LR_ITEM) * size);
    
    // add items to the heap [O(N log N)]
    for (itr = I, i = 0; itr; itr = itr->next, i++)
    {
        heap[i] = itr->item;
        int a = i; int b = (i-1)/2;
        while (a > 0 && CompareItems(heap[a], heap[b]) < 0)
        {
            SWAP_ITEMS(&heap[a], &heap[b]);
            a = b;
            b = (b-1)/2;
        }
    }
    
    // pop items off the heap [O(N log N)]
    for (itr = I; itr; itr = itr->next)
    {
        itr->item = heap[0];
        size--;
        heap[0] = heap[size];
        
        int j = 0;
        int a = 1; int b = 2;
        while (j < size &&
               ((a < size && CompareItems(heap[j], heap[a]) > 0)
             || (b < size && CompareItems(heap[j], heap[b]) > 0)))
        {
            if (b < size && CompareItems(heap[a], heap[b]) > 0)
            {
                SWAP_ITEMS(&heap[b], &heap[j]);
                j = b;
            }
            else
            {
                SWAP_ITEMS(&heap[a], &heap[j]);
                j = a;
            }
            a = 2*j + 1;
            b = 2*j + 2;
        }
    }
    
    // free memory [O(1)]
    free(heap);
    return I;
}
Example #14
0
void CXmlItem::SortItems(const CString& sItemName, const CString& sKeyName, XI_SORTKEY nKey, BOOL bAscending)
{
	if (!sItemName || !sKeyName)
		return;
	
	// 1. sort immediate children first
	CXmlItem* pXIItem = GetItem(sItemName);
	
	if (!pXIItem)
		return;
	
	// make sure item has key value
	if (!pXIItem->GetItem(sKeyName))
		return;
	
	// make sure at least one sibling exists
	BOOL bContinue = (pXIItem->GetSibling() != NULL);
	
	while (bContinue)
	{
		CXmlItem* pXIPrev = NULL;
		CXmlItem* pXISibling = NULL;
		
		// get this again because we have to anyway 
		// for subsequent loops
		pXIItem = GetItem(sItemName);
		POSITION pos = m_lstItems.Find(pXIItem);
		
		// reset continue flag so that if there are no
		// switches then the sorting is done
		bContinue = FALSE;
		pXISibling = pXIItem->GetSibling();
		
		while (pXISibling)
		{
			int nCompare = CompareItems(pXIItem, pXISibling, sKeyName, nKey);
			
			if (!bAscending)
				nCompare = -nCompare;
			
			if (nCompare > 0)
			{
				// switch items
				if (pXIPrev)
					pXIPrev->m_pSibling = pXISibling;
				
				else // we're at the head of the chain
				{
					m_lstItems.SetAt(pos, pXISibling);
					//	m_mapItems[sItemName] = pXISibling;
				}
				
				pXIItem->m_pSibling = pXISibling->m_pSibling;
				pXISibling->m_pSibling = pXIItem;
				pXIPrev = pXISibling;
				
				bContinue = TRUE; // loop once more
			}
			else
			{
				pXIPrev = pXIItem;
				pXIItem = pXISibling;
			}
			
			pXISibling = pXIItem->GetSibling(); // next
		}
	}
	
	// 2. sort children's children
	pXIItem = GetItem(sItemName);
	
	while (pXIItem)
	{
		pXIItem->SortItems(sItemName, sKeyName, nKey, bAscending);
		pXIItem = pXIItem->GetSibling();
	}
}