/* * 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; }
/** * 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; }