147 lines
5.3 KiB
C
147 lines
5.3 KiB
C
/*
|
|
* Předmět: Algoritmy (IAL) - FIT VUT v Brně
|
|
* Rozšíření pro příklad c206.c (Dvousměrně vázaný lineární seznam)
|
|
* Vytvořil: Daniel Dolejška, září 2024
|
|
*/
|
|
|
|
#include "c206-ext.h"
|
|
|
|
bool error_flag;
|
|
bool solved;
|
|
|
|
/**
|
|
* Tato metoda simuluje příjem síťových paketů s určenou úrovní priority.
|
|
* Přijaté pakety jsou zařazeny do odpovídajících front dle jejich priorit.
|
|
* "Fronty" jsou v tomto cvičení reprezentovány dvousměrně vázanými seznamy
|
|
* - ty totiž umožňují snazší úpravy pro již zařazené položky.
|
|
*
|
|
* Parametr `packetLists` obsahuje jednotlivé seznamy paketů (`QosPacketListPtr`).
|
|
* Pokud fronta s odpovídající prioritou neexistuje, tato metoda ji alokuje
|
|
* a inicializuje. Za jejich korektní uvolnení odpovídá volající.
|
|
*
|
|
* V případě, že by po zařazení paketu do seznamu počet prvků v cílovém seznamu
|
|
* překročil stanovený MAX_PACKET_COUNT, dojde nejdříve k promazání položek seznamu.
|
|
* V takovémto případě bude každá druhá položka ze seznamu zahozena nehledě
|
|
* na její vlastní prioritu ovšem v pořadí přijetí.
|
|
*
|
|
* @param packetLists Ukazatel na inicializovanou strukturu dvousměrně vázaného seznamu
|
|
* @param packet Ukazatel na strukturu přijatého paketu
|
|
*/
|
|
void receive_packet(DLList *packetLists, PacketPtr packet) {
|
|
QosPacketListPtr targetList = NULL;
|
|
DLL_First(packetLists);
|
|
while (DLL_IsActive(packetLists)) {
|
|
QosPacketListPtr currentList = (QosPacketListPtr)((long)packetLists->activeElement->data);
|
|
if (currentList->priority == packet->priority) {
|
|
targetList = currentList;
|
|
break;
|
|
}
|
|
if (currentList->priority < packet->priority) {
|
|
break;
|
|
}
|
|
DLL_Next(packetLists);
|
|
}
|
|
|
|
if (targetList == NULL) {
|
|
|
|
targetList = (QosPacketListPtr)malloc(sizeof(QosPacketList));
|
|
if (targetList == NULL) {
|
|
error_flag = true;
|
|
return;
|
|
}
|
|
targetList->priority = packet->priority;
|
|
targetList->list = (DLList *)malloc(sizeof(DLList));
|
|
if (targetList->list == NULL) {
|
|
free(targetList);
|
|
error_flag = true;
|
|
return;
|
|
}
|
|
DLL_Init(targetList->list);
|
|
|
|
|
|
if (!DLL_IsActive(packetLists)) {
|
|
DLL_InsertLast(packetLists, (long)targetList);
|
|
} else {
|
|
DLL_InsertBefore(packetLists, (long)targetList);
|
|
}
|
|
}
|
|
|
|
if (targetList->list->currentLength >= MAX_PACKET_COUNT) {
|
|
DLLElementPtr current = targetList->list->firstElement;
|
|
DLLElementPtr next;
|
|
int count = 0;
|
|
while (current != NULL) {
|
|
next = current->nextElement;
|
|
if (count % 2 == 1) {
|
|
|
|
if (current == targetList->list->activeElement) {
|
|
targetList->list->activeElement = next;
|
|
}
|
|
if (current == targetList->list->firstElement) {
|
|
targetList->list->firstElement = next;
|
|
}
|
|
if (current == targetList->list->lastElement) {
|
|
targetList->list->lastElement = current->previousElement;
|
|
}
|
|
if (current->previousElement) {
|
|
current->previousElement->nextElement = next;
|
|
}
|
|
if (next) {
|
|
next->previousElement = current->previousElement;
|
|
}
|
|
free(current);
|
|
targetList->list->currentLength--;
|
|
}
|
|
current = next;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
|
|
DLL_InsertLast(targetList->list, (long)packet);
|
|
}
|
|
|
|
/**
|
|
* Tato metoda simuluje výběr síťových paketů k odeslání. Výběr respektuje
|
|
* relativní priority paketů mezi sebou, kde pakety s nejvyšší prioritou
|
|
* jsou vždy odeslány nejdříve. Odesílání dále respektuje pořadí, ve kterém
|
|
* byly pakety přijaty metodou `receive_packet`.
|
|
*
|
|
* Odeslané pakety jsou ze zdrojového seznamu při odeslání odstraněny.
|
|
*
|
|
* Parametr `packetLists` obsahuje ukazatele na jednotlivé seznamy paketů (`QosPacketListPtr`).
|
|
* Parametr `outputPacketList` obsahuje ukazatele na odeslané pakety (`PacketPtr`).
|
|
*
|
|
* @param packetLists Ukazatel na inicializovanou strukturu dvousměrně vázaného seznamu
|
|
* @param outputPacketList Ukazatel na seznam paketů k odeslání
|
|
* @param maxPacketCount Maximální počet paketů k odeslání
|
|
*/
|
|
void send_packets(DLList *packetLists, DLList *outputPacketList, int maxPacketCount) {
|
|
int sentCount = 0;
|
|
|
|
while (sentCount < maxPacketCount) {
|
|
|
|
DLL_First(packetLists);
|
|
|
|
while (DLL_IsActive(packetLists) && sentCount < maxPacketCount) {
|
|
QosPacketListPtr currentList = (QosPacketListPtr)((long)packetLists->activeElement->data);
|
|
|
|
if (currentList->list->currentLength > 0) {
|
|
|
|
PacketPtr packet = (PacketPtr)((long)currentList->list->firstElement->data);
|
|
DLL_InsertLast(outputPacketList, (long)packet);
|
|
DLL_DeleteFirst(currentList->list);
|
|
sentCount++;
|
|
} else {
|
|
|
|
DLL_Next(packetLists);
|
|
}
|
|
}
|
|
|
|
if (!DLL_IsActive(packetLists)) {
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|