int main() { List *list = newList(); listAddLast(list, "One"); listAddLast(list, "Two"); listAddLast(list, "Three"); listAddFirst(list, "One"); listAddFirst(list, "Two"); listAddFirst(list, "Three"); print_list(list); listRemoveFirst(list); print_list(list); listRemoveLast(list); print_list(list); listClear(list); listAddLast(list, "One"); listRemoveFirst(list); print_list(list); listAddFirst(list, "One"); listAddLast(list, "One"); listAddFirst(list, "Two"); listAddLast(list, "Two"); listAddFirst(list, "Three"); listAddLast(list, "Three"); print_list(list); deleteList(list); return 0; }
void listRemoveNode(List *L, NodeList *p){ if(!listNodeExists(L, p)) return ; if(p == L->last) listRemoveLast(L); else if(p == L->header) listRemoveFirst(L); else{ NodeList *ant = listGetPrevious(L, p); ant->next = p->next; p->next = NULL; } return; }
static int connectionSubmitRequests(externalServer_t* pServer, connectionContext_t* pCContext) { //we have a free connection int count = MAX_MULTI_GET_REQUESTS; while (count-- > 0) { request_t* pRequest = listRemoveFirst(pServer->unassignedRequests); if (!pRequest) { break; } listAddLast(pCContext->currentRequests, pRequest); } if (listGetSize(pCContext->currentRequests) > 0) { listAddLast(pServer->activeConnections, pCContext); int bytesWritten = connectionMakeGetRequest(pCContext); if (bytesWritten > 0) { int err = completeWrite(pCContext); if (err == 0) { pCContext->status = status_waiting_read; connectionWaitForRead(pCContext->connection, getGlobalEventBase()); }else { if (err == 1) { pCContext->status = status_waiting_write; connectionWaitForWrite(pCContext->connection, getGlobalEventBase()); }else { // error writing to server/ connection closed ? listRemove(pServer->activeConnections, pCContext); connectionContextDelete(pCContext, 1); } } } }else { //pooled connections also wait for read, incase they are close by the server pCContext->status = status_pooled; listAddLast(pServer->freeConnections, pCContext); connectionWaitForRead(pCContext->connection, getGlobalEventBase()); } return 0; }
static int externalServerSubmit(externalServer_t* pServer, request_t* pRequest) { int returnValue = 0; connectionContext_t* pCContext = 0; connection_t newConnection = 0; listAddLast(pServer->unassignedRequests, pRequest); pCContext = listRemoveFirst(pServer->freeConnections); if (pCContext) { connectionWaitCancel(pCContext->connection, getGlobalEventBase()); } if (!pCContext) { //check if we have reached max concurrent connections limit // if not, create a new connection if (listGetSize(pServer->activeConnections) < MAX_CONCURRENT_CONNECTIONS) { LOG(DEBUG, "creating new external connection"); newConnection = connectionClientCreate(pServer->serverIP, pServer->serverPort, createConnectionHandler()); IfTrue(newConnection, ERR, "Error creating new connection to %s", pServer->serverName); //got a new connection pCContext = connectionContextCreate(newConnection, pServer); IfTrue(pCContext, ERR, "Error allocting memory for connection context"); connectionSetContext(newConnection, pCContext); newConnection = 0; int err = connectionConnect(pCContext->connection); IfTrue(err >= 0, ERR, "connect failed"); if (err == 1) { LOG(DEBUG, "waiting for connect to complete"); pCContext->status = status_connecting; connectionWaitForConnect(pCContext->connection, getGlobalEventBase()); goto OnSuccess; } }else { //if we have reached max connection limit, we will let the request rest //in the queue. Whenever one of the current connections get free, we will //use that to send the request. returnValue = 1; goto OnSuccess; } } if (pCContext) { pCContext->status = status_active; connectionSubmitRequests(pServer, pCContext); } goto OnSuccess; OnError: if (newConnection) { connectionClose(newConnection); } if (pCContext) { connectionContextDelete(pCContext, 0); } returnValue = 1; OnSuccess: return returnValue; }
static void readAvailableImpl(connection_t connection){ connectionContext_t* pCContext = connectionGetContext(connection); u_int32_t bytesRead = 0; int returnValue = 0; LOG(DEBUG, "got something to read on socket"); //if it is one of the pooled connections if (pCContext->status == status_pooled) { LOG(DEBUG, "socket was pooled..closing on read"); //socket is closed externalServer_t* pServer = pCContext->pExternalServer; listRemove(pServer->freeConnections, pCContext); connectionContextDelete(pCContext, 0); goto OnSuccess; } if (pCContext->status == status_waiting_read) { pCContext->status = status_active; }else { LOG(ERR, "Invalid connection state"); goto OnError; } returnValue = connectionRead(pCContext->connection, pCContext->fallocator, pCContext->readStream, 8 * 1024 , &bytesRead); LOG(DEBUG, "connection read status %d bytesRead %d", returnValue, bytesRead); IfTrue(returnValue >= 0, INFO, "Socket closed"); doParseMore: returnValue = responseParserParse(pCContext->parser, pCContext->readStream); LOG(DEBUG, "response parser status %d", returnValue); IfTrue(returnValue >= 0, INFO, "Parsing Error %d", returnValue); if (returnValue == 1) { LOG(DEBUG, "need to wait for read"); pCContext->status = status_waiting_read; connectionWaitForRead(pCContext->connection, getGlobalEventBase()); goto OnSuccess; } char* key = 0; dataStream_t value = 0; u_int32_t flags = 0; returnValue = responseParserGetResponse(pCContext->parser, pCContext->readStream, &key, &value, &flags); LOG(DEBUG, "got resposonse %d key %s", returnValue, key); if (returnValue == 0) { externalServer_t* pServer = pCContext->pExternalServer; clusterMapImpl_t* pCM = pServer->pClusterMap; request_t* pRequest = 0; tryNext: pRequest = listRemoveFirst(pCContext->currentRequests); if (pRequest) { if (0 == strcmp(pRequest->key, key)) { //we got the response for the key LOG(DEBUG, "giving callback for success result"); pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, 0, value); dataStreamDelete(value); value = 0; fallocatorFree(pCContext->fallocator, key); key = 0; deleteRequest(pRequest); pRequest = 0; goto doParseMore; }else { //this key is different from the key we expected //the request for current key failed, so notify LOG(DEBUG, "giving callback for fail result"); pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, -1, NULL); deleteRequest(pRequest); pRequest = 0; //move on to the next key, may be its her response goto tryNext; } }else { // no more request in the currentRequests list? // what this means is that we got a response for a key // which we didn't asked for... // that is strange.., some server issue..we can't do much dataStreamDelete(value); value = 0; fallocatorFree(pCContext->fallocator, key); key = 0; // now so just close this connection externalServer_t* pServer = pCContext->pExternalServer; listRemove(pServer->activeConnections, pCContext); connectionContextDelete(pCContext, 0); pCContext = 0; } }else { LOG(DEBUG, "end of results from response parser"); // we go END response from parser externalServer_t* pServer = pCContext->pExternalServer; clusterMapImpl_t* pCM = pServer->pClusterMap; request_t* pRequest = 0; //anything pending in the currentRequests..not found while ((pRequest = listRemoveLast(pCContext->currentRequests)) != 0) { //report error pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, -1, NULL); deleteRequest(pRequest); } // add this connections to free connections list listRemove(pServer->activeConnections, pCContext); connectionSubmitRequests(pServer, pCContext); } goto OnSuccess; OnError: if (pCContext) { externalServer_t* pServer = pCContext->pExternalServer; listRemove(pServer->activeConnections, pCContext); connectionContextDelete(pCContext, 1); pCContext = 0; } OnSuccess: return; }
/** Add first element into linkedlist HEAD HEAD ------- -------- ------- | NULL | ----> | ele1 |-----| NULL | ------- -------- ------- **/ void test_listAddFirst_should_add_first_element_into_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; listAddFirst(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); } /** Add elements into linkedlist HEAD HEAD TAIL ------- ------ ----- ----- ------ ------ ----- | NULL | ----> |ele5|-----|ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL| ------- ------ ----- ------ ------ ------ ------ **/ void test_listAddFirst_should_add_elements_into_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; Element ele2 = {.next = (Element *)NULL, .data = (Element *)5}; Element ele3 = {.next = (Element *)NULL, .data = (Element *)10}; Element ele4 = {.next = (Element *)NULL, .data = (Element *)15}; Element ele5 = {.next = (Element *)NULL, .data = (Element *)20}; listAddFirst(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele2,list); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(5,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele3,list); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(10,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele4,list); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(15,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele5,list); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(20,list->head->data); TEST_ASSERT_EQUAL(15,list->head->next->data); TEST_ASSERT_EQUAL(10,list->head->next->next->data); TEST_ASSERT_EQUAL(5,list->head->next->next->next->data); TEST_ASSERT_EQUAL(1,list->head->next->next->next->next->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data); TEST_ASSERT_EQUAL(list->head->next->next->next->next->data,list->tail->data); TEST_ASSERT_EQUAL(5,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); } /** Remove elements into linkedlist Add ele1 HEAD HEAD ------- ------ ----- | NULL | ----> |ele1|----|NULL| ------- ------ ------ Remove ele1 HEAD ------ |NULL| ------ **/ void test_listRemoveFirst_should_remove_first_element_from_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; listAddFirst(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listRemoveFirst(list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(NULL,list->head); TEST_ASSERT_EQUAL(NULL,list->tail); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(0,list->length); TEST_ASSERT_NULL(list->head); TEST_ASSERT_NULL(list->tail); } /** Add elements into linkedlist HEAD HEAD TAIL ------- ------ ----- ----- ------ ------ ----- | NULL | ----> |ele5|-----|ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL| ------- ------ ----- ------ ------ ------ ------ Remove element 5 from head HEAD TAIL ------ ----- ----- ------ ----- |ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL| ------ ----- ------ ------ ------ Remove element 4 from head HEAD TAIL ------ ----- ----- ----- |ele3|-----|ele2|-----|ele1|-----|NULL| ------ ----- ------ ------ Remove element 3 from head HEAD TAIL ------ ----- ----- |ele2|-----|ele1|-----|NULL| ------ ----- ------ Remove element 2 from head HEAD ------ ----- |ele1|-----|NULL| ------ ------ Remove element 1 from head HEAD ------ |NULL| ------ **/ void test_listRemoveFirst_should_remove_elements_from_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; Element ele2 = {.next = (Element *)NULL, .data = (Element *)5}; Element ele3 = {.next = (Element *)NULL, .data = (Element *)10}; Element ele4 = {.next = (Element *)NULL, .data = (Element *)15}; Element ele5 = {.next = (Element *)NULL, .data = (Element *)20}; listAddFirst(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele2,list); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(5,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele3,list); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(10,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele4,list); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(15,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddFirst(&ele5,list); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(20,list->head->data); TEST_ASSERT_EQUAL(15,list->head->next->data); TEST_ASSERT_EQUAL(10,list->head->next->next->data); TEST_ASSERT_EQUAL(5,list->head->next->next->next->data); TEST_ASSERT_EQUAL(1,list->head->next->next->next->next->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data); TEST_ASSERT_EQUAL(list->head->next->next->next->next->data,list->tail->data); TEST_ASSERT_EQUAL(5,list->length); TEST_ASSERT_NOT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listRemoveFirst(list); //Removed 20 from the head TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(15,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveFirst(list); //Removed 15 from the head TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(10,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveFirst(list); //Removed 10 from the head TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(5,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveFirst(list); //Removed 5 from the head TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveFirst(list); //Removed 1 from the head TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(NULL,list->head); TEST_ASSERT_EQUAL(NULL,list->tail); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(0,list->length); TEST_ASSERT_NULL(list->head); TEST_ASSERT_NULL(list->tail); } /** Add first element into linkedlist HEAD HEAD ------- -------- ------- | NULL | ----> | ele1 |-----| NULL | ------- -------- ------- **/ void test_listAddLast_should_add_first_element_into_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; listAddLast(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); } /** Add elements into linkedlist HEAD HEAD TAIL ------- ------ ----- ----- ------ ------ ----- | NULL | ----> |ele1|-----|ele2|-----|ele3|-----|ele4|-----|ele5|-----|NULL| ------- ------ ----- ------ ------ ------ ------ **/ void test_listAddLast_should_add_elements_into_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; Element ele2 = {.next = (Element *)NULL, .data = (Element *)5}; Element ele3 = {.next = (Element *)NULL, .data = (Element *)10}; Element ele4 = {.next = (Element *)NULL, .data = (Element *)15}; Element ele5 = {.next = (Element *)NULL, .data = (Element *)20}; listAddLast(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddLast(&ele2,list); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(5,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele3,list); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(10,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele4,list); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(15,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele5,list); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(20,list->tail->data); TEST_ASSERT_EQUAL(15,list->tail->next->data); TEST_ASSERT_EQUAL(10,list->tail->next->next->data); TEST_ASSERT_EQUAL(5,list->tail->next->next->next->data); TEST_ASSERT_EQUAL(1,list->tail->next->next->next->next->data); TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->next->data); TEST_ASSERT_EQUAL(5,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); } void test_listRemoveLast_should_remove_first_element_from_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; listAddLast(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listRemoveLast(list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(NULL,list->head); TEST_ASSERT_EQUAL(NULL,list->tail); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(0,list->length); TEST_ASSERT_NULL(list->head); TEST_ASSERT_NULL(list->tail); } /** Add elements into linkedlist HEAD HEAD TAIL ------- ------ ----- ----- ------ ------ ----- | NULL | ----> |ele1|-----|ele2|-----|ele3|-----|ele4|-----|ele5|-----|NULL| ------- ------ ----- ------ ------ ------ ------ Remove element 5 from tail HEAD TAIL ------ ----- ----- ------ ----- |ele1|-----|ele2|-----|ele3|-----|ele4|-----|NULL| ------ ----- ------ ------ ------ Remove element 4 from tail HEAD TAIL ------ ----- ----- ----- |ele1|-----|ele2|-----|ele3|-----|NULL| ------ ----- ------ ------ Remove element 3 from tail HEAD TAIL ------ ----- ----- |ele1|-----|ele2|-----|NULL| ------ ----- ------ Remove element 2 from tail HEAD ------ ----- |ele1|-----|NULL| ------ ------ Remove element 1 from tail HEAD ------ |NULL| ------ **/ void test_listRemoveLast_should_remove_elements_from_linkedList() { LinkedList *list = createLinkedList(); Element ele1 = {.next = (Element *)NULL, .data = (Element *)1}; Element ele2 = {.next = (Element *)NULL, .data = (Element *)5}; Element ele3 = {.next = (Element *)NULL, .data = (Element *)10}; Element ele4 = {.next = (Element *)NULL, .data = (Element *)15}; Element ele5 = {.next = (Element *)NULL, .data = (Element *)20}; listAddLast(&ele1,list); TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NULL(list->tail->next); listAddLast(&ele2,list); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(5,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele3,list); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(10,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele4,list); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(15,list->tail->data); TEST_ASSERT_NOT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listAddLast(&ele5,list); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(20,list->tail->data); TEST_ASSERT_EQUAL(15,list->tail->next->data); TEST_ASSERT_EQUAL(10,list->tail->next->next->data); TEST_ASSERT_EQUAL(5,list->tail->next->next->next->data); TEST_ASSERT_EQUAL(1,list->tail->next->next->next->next->data); TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->next->data); TEST_ASSERT_EQUAL(5,list->length); TEST_ASSERT_NULL(list->head->next); TEST_ASSERT_NOT_NULL(list->tail->next); listRemoveLast(list); //Removed 20 from the tail TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(15,list->tail->data); TEST_ASSERT_EQUAL(10,list->tail->next->data); TEST_ASSERT_EQUAL(5,list->tail->next->next->data); TEST_ASSERT_EQUAL(1,list->tail->next->next->next->data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->data); TEST_ASSERT_EQUAL(4,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveLast(list); //Removed 15 from the tail TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(10,list->tail->data); TEST_ASSERT_EQUAL(5,list->tail->next->data); TEST_ASSERT_EQUAL(1,list->tail->next->next->data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->data); TEST_ASSERT_EQUAL(3,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveLast(list); //Removed 10 from the tail TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(5,list->tail->data); TEST_ASSERT_EQUAL(1,list->tail->next->data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->next->data); TEST_ASSERT_EQUAL(2,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveLast(list); //Removed 5 from the tail TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(1,list->tail->data); TEST_ASSERT_EQUAL(1,list->head->data); TEST_ASSERT_EQUAL(list->head->data,list->tail->data); TEST_ASSERT_EQUAL(1,list->length); TEST_ASSERT_NOT_NULL(list->head); TEST_ASSERT_NOT_NULL(list->tail); listRemoveLast(list); //Removed 1 from the tail TEST_ASSERT_EQUAL(1,ele1.data); TEST_ASSERT_EQUAL(5,ele2.data); TEST_ASSERT_EQUAL(10,ele3.data); TEST_ASSERT_EQUAL(15,ele4.data); TEST_ASSERT_EQUAL(20,ele5.data); TEST_ASSERT_EQUAL(NULL,list->tail); TEST_ASSERT_EQUAL(NULL,list->head); TEST_ASSERT_EQUAL(list->head,list->tail); TEST_ASSERT_EQUAL(0,list->length); TEST_ASSERT_NULL(list->head); TEST_ASSERT_NULL(list->tail); }