Esempio n. 1
0
/*
 * Creates a new map entry
 *
 * @return void * retptr != NULL: The new entry.
 * @return void * retptr == NULL: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory.
 */
static PblMapEntry * pblMapEntryNew( void * key, /**                     Key to add a mapping for  */
size_t keyLength, /**               Length of the key         */
void * value, /**                   Value of the new mapping  */
size_t valueLength /**              Length of the value       */
)
{
    PblMapEntry * newEntry = (PblMapEntry *)pbl_malloc( "pblMapEntryNew", sizeof(PblMapEntry)
            + keyLength + valueLength );
    if( !newEntry )
    {
        return NULL;
    }

    newEntry->tag = PBL_MAP_ENTRY_TAG;
    newEntry->keyLength = keyLength;
    if( keyLength > 0 )
    {
        memcpy( newEntry->buffer, key, keyLength);
    }
    newEntry->valueLength = valueLength;
    if( valueLength > 0 )
    {
        memcpy( newEntry->buffer + keyLength, value, valueLength );
    }
    //MEMORY_FIX: Freeing value, since it's been memcpy'd.
    //free(value);
    return newEntry;
}
/**
 * Returns a reverse iterator over the elements in this collection in proper sequence.
 *
 * The reverse iterator starts the iteration at the end of the collection.
 *
 * <B>Note:</B> The memory allocated by this method for the iterator returned needs to be released
 *       by calling pblIteratorFree() once the iterator is no longer needed.
 *
 * The iterators returned by the this method are fail-fast:
 * if the collection is structurally modified at any time after the iterator is created,
 * in any way except through the Iterator's own remove or add methods,
 * the iterator will return a PBL_ERROR_CONCURRENT_MODIFICATION error.
 *
 * Thus, in the face of concurrent modification,
 * the iterator fails quickly and cleanly,
 * rather than risking arbitrary, non-deterministic
 * behavior at an undetermined time in the future.
 *
 * This method has a time complexity of O(1).
 *
 * @return void * retptr != NULL: The iterator.
 * @return void * retptr == NULL: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY      - Out of memory.
 * <BR>PBL_COLLECTION_IS_COLLECTION - The collection cannot be iterated.
 */
PblIterator * pblIteratorReverseNew(
PblCollection * collection          /** The collection to create the iterator for */
)
{
    PblIterator * iterator;

    if( !PBL_COLLECTION_IS_COLLECTION( collection ) )
    {
        pbl_errno = PBL_ERROR_PARAM_COLLECTION;
        return NULL;
    }

    iterator = pbl_malloc( "pblIteratorReverseNew", sizeof(PblIterator) );
    if( !iterator )
    {
        return NULL;
    }

    if( pblIteratorReverseInit( collection, iterator ) < 0 )
    {
        PBL_FREE( iterator );
        return NULL;
    }

    return (PblIterator *)iterator;
}
Esempio n. 3
0
/**
 * Adds the element with the specified priority to the
 * end of the priority queue without ensuring the
 * heap condition.
 *
 * This function has a time complexity of O(1).
 *
 * This function together with \Ref{pblPriorityQueueConstruct}()
 * can be used to build a priority queue with N elements
 * in time proportional to N.
 *
 * First create an empty queue with \Ref{pblPriorityQueueNew}()
 * and ensure the queue has space for N elements via a
 * call to \Ref{pblPriorityQueueEnsureCapacity}(),
 * then add all elements via calls to this function
 * and finally ensure the heap condition with a call
 * to \Ref{pblPriorityQueueConstruct}().
 *
 * @return int rc >= 0: The size of the queue.
 * @return int rc <  0: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory.
 */
int pblPriorityQueueAddLast( /*                       */
PblPriorityQueue * queue, /** The queue to use        */
int priority, /** Priority of the element to be added */
void * element /** Element to be added to the queue   */
)
{
	int rc;
	PblPriorityQueueEntry *newEntry = (PblPriorityQueueEntry *) pbl_malloc("pblPriorityQueueAddLast",
			sizeof(PblPriorityQueueEntry));
	if (!newEntry)
	{
		return -1;
	}

	newEntry->element = element;
	newEntry->priority = priority;

	rc = pblHeapAddLast((PblHeap *) queue, newEntry);
	if (rc < 0)
	{
		PBL_FREE(newEntry);
		return rc;
	}

	return pblHeapSize((PblHeap *) queue);
}
/**
 * Inserts the specified element into the underlying collection.
 *
 * The element is inserted immediately before the next element that would be returned by next,
 * if any, and after the next element that would be returned by previous, if any.
 *
 * If the list contains no elements, the new element becomes the sole element on the list.
 *
 * The new element is inserted before the implicit cursor:
 * a subsequent call to next would be unaffected,
 * and a subsequent call to previous would return the new element.
 * This call increases by one the value that would be returned by a
 * call to nextIndex or previousIndex.
 *
 * For array lists this method has a time complexity of O(N),
 * with N being the number of elements in the underlying list.
 *
 * For linked lists this method has a time complexity of O(1).
 *
 * @return int rc >= 0: The size of the list.
 * @return int rc <  0: An error, see pbl_errno:
 *
 * <BR>PBL_ERROR_OUT_OF_MEMORY           - Out of memory.
 * <BR>PBL_ERROR_CONCURRENT_MODIFICATION - The underlying list was modified concurrently.
 * <BR>PBL_ERROR_PARAM_LIST              - The underlying collection is not a list.
 */
int pblIteratorAdd(
PblIterator * iterator, /** The iterator to add the element to */
void * element          /** Element to be added to this list   */
)
{
    PblList * list = (PblList*)iterator->collection;

    if( !PBL_LIST_IS_LIST( list ) )
    {
        pbl_errno = PBL_ERROR_PARAM_LIST;
        return -1;
    }

    if( iterator->changeCounter != list->changeCounter )
    {
        pbl_errno = PBL_ERROR_CONCURRENT_MODIFICATION;
        return -1;
    }

    if( list->size == 0 )
    {
        if( pblListAdd( (PblList*)list, element ) < 1 )
        {
            return -1;
        }

        iterator->index = 1;
        iterator->next = NULL;

        iterator->lastIndexReturned = -1;
        iterator->current = NULL;

        if( PBL_LIST_IS_LINKED_LIST( list ) )
        {
            PblLinkedList * linkedList = (PblLinkedList*)list;
            iterator->prev = linkedList->tail;
        }
        iterator->changeCounter = list->changeCounter;
        return 1;
    }

    if( PBL_LIST_IS_ARRAY_LIST( list ) )
    {
        int rc = pblListAddAt( (PblList*)list, iterator->index, element );
        if( rc < 0 )
        {
            return -1;
        }
    }
    else
    {
        PblLinkedList * linkedList = (PblLinkedList*)list;
        PblLinkedNode * newNode = pbl_malloc( "pblIteratorAdd",
                                              sizeof(PblLinkedNode) );
        if( !newNode )
        {
            return -1;
        }
        newNode->element = element;

        if( !iterator->next )
        {
            PBL_LIST_APPEND( linkedList->head, linkedList->tail, newNode, next, prev );
        }
        else
        {
            PBL_LIST_INSERT( linkedList->head, iterator->next, newNode, next, prev );
        }
        linkedList->genericList.size++;
        linkedList->genericList.changeCounter++;

        iterator->prev = newNode;
    }

    iterator->lastIndexReturned = -1;
    iterator->current = NULL;

    iterator->index++;

    iterator->changeCounter = list->changeCounter;
    return list->size;
}