added LRU and fixed bug in dequeueN
This commit is contained in:
@ -453,7 +453,7 @@ void readNFiles(int num, queueT *q, long fd_c, taglia_t *taglia) {
|
||||
toSend[i]->filepath,
|
||||
toSend[i]->valid);
|
||||
}
|
||||
n += snprintf(tmp_buf+n, m-n, "readNFile dimensione totale = %ld\n",
|
||||
n += snprintf(tmp_buf+n, m-n, "readNFile dimensione totale = %ld B\n",
|
||||
tot);
|
||||
|
||||
sendMessageFileN(MEOK, toSend, ntosend, fd_c, taglia, tmp_buf);
|
||||
|
||||
@ -129,7 +129,7 @@ int enqueue(queueT *q, fileT* data) {
|
||||
goto _end_enqueue;
|
||||
}
|
||||
|
||||
/* insert the element */
|
||||
/* insert the element at the end */
|
||||
nodeT *newNode = malloc(sizeof(nodeT));
|
||||
if (newNode == NULL) {
|
||||
perror("enqueue: malloc");
|
||||
@ -178,6 +178,7 @@ fileT* dequeue(queueT *q) {
|
||||
|
||||
fileT *data = (q->head)->data;
|
||||
|
||||
/* dequeue the first in the list */
|
||||
nodeT *tmp = NULL;
|
||||
tmp = q->head;
|
||||
q->head = (q->head)->next;
|
||||
@ -217,17 +218,26 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
|
||||
if(q->maxSize > s) {
|
||||
if(q->maxSize < s) {
|
||||
errno = EINVAL;
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
|
||||
/* try to find the file */
|
||||
nodeT *tmp = q->head;
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
nodeT *prev = NULL;
|
||||
#endif
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||
break;
|
||||
}
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
prev = tmp;
|
||||
#endif
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@ -236,39 +246,80 @@ fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
|
||||
tmp = NULL;
|
||||
nodeT* file = tmp;
|
||||
|
||||
/* if LRU put the file at the end */
|
||||
#if ALGORITHM == 1
|
||||
if(prev==NULL && tmp->next==NULL) {
|
||||
q->head = tmp;
|
||||
q->tail = tmp;
|
||||
} else if(prev==NULL) {
|
||||
q->head = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
} else if(tmp->next!=NULL) {
|
||||
prev->next = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
}
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
tmp = q->head;
|
||||
|
||||
returnList = calloc(1, sizeof(*returnList));
|
||||
if(!returnList) {
|
||||
perror("dequeueN: calloc");
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
returnList[0] = NULL;
|
||||
|
||||
int purged = 0;
|
||||
int addFileAtEnd = 0;
|
||||
while(q->size + s > q->maxSize) {
|
||||
purged++;
|
||||
if (q->head == NULL) { /* queue becomes empty */
|
||||
q->tail = NULL;
|
||||
break; /* we eliminated everything so we must have enought space */
|
||||
}
|
||||
if(q->head == file) { /* dont delete the file to expand */
|
||||
q->head = q->head->next;
|
||||
addFileAtEnd = 1;
|
||||
}
|
||||
|
||||
tmp = q->head;
|
||||
q->head = q->head->next;
|
||||
|
||||
++purged;
|
||||
returnList = realloc(returnList, purged * sizeof(fileT*));
|
||||
if(!returnList) {
|
||||
perror("dequeueN: realloc");
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
tmp = q->head;
|
||||
q->head = (q->head)->next;
|
||||
|
||||
returnList[purged-1] = tmp->data;
|
||||
--q->len;
|
||||
q->size -= tmp->data->size;
|
||||
|
||||
if (q->head == NULL) { /* queue becomes empty */
|
||||
q->tail = NULL;
|
||||
break; /* we eliminated everything so we must have enought space */
|
||||
free(tmp); /* free of the node */
|
||||
}
|
||||
if(addFileAtEnd == 1) {
|
||||
/* if LRU, we know already that this code is unrechable
|
||||
* and that q->head must be NULL if rechable */
|
||||
if(q->head == NULL) {
|
||||
q->head = file;
|
||||
q->head->next = NULL;
|
||||
} else {
|
||||
file->next = q->head;
|
||||
q->head = file;
|
||||
}
|
||||
}
|
||||
|
||||
returnList = realloc(returnList, (purged+1) * sizeof(fileT*));
|
||||
if(!returnList) {
|
||||
perror("dequeueN: realloc");
|
||||
goto _end_dequeueN;
|
||||
}
|
||||
returnList[purged] = NULL; /* null terminated */
|
||||
|
||||
tmp->data->size += s;
|
||||
file->data->size += s;
|
||||
q->size += s;
|
||||
|
||||
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||
@ -357,11 +408,19 @@ int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
||||
|
||||
/* find file */
|
||||
nodeT *tmp = q->head;
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
nodeT *prev = NULL;
|
||||
#endif
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||
break;
|
||||
}
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
prev = tmp;
|
||||
#endif
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@ -380,6 +439,25 @@ int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
||||
(tmp->data)->O_LOCK = 1;
|
||||
(tmp->data)->owner = owner;
|
||||
|
||||
/* if LRU put the file at the end */
|
||||
#if ALGORITHM == 1
|
||||
if(prev==NULL && tmp->next==NULL) {
|
||||
q->head = tmp;
|
||||
q->tail = tmp;
|
||||
} else if(prev==NULL) {
|
||||
q->head = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
} else if(tmp->next!=NULL) {
|
||||
prev->next = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
}
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
|
||||
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||
return 0;
|
||||
|
||||
@ -455,10 +533,19 @@ int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
||||
|
||||
/* find the file */
|
||||
nodeT *tmp = q->head;
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
nodeT *prev = NULL;
|
||||
#endif
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||
break;
|
||||
}
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
prev = tmp;
|
||||
#endif
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@ -480,6 +567,24 @@ int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
||||
(tmp->data)->owner = owner;
|
||||
}
|
||||
|
||||
/* if LRU put the file at the end */
|
||||
#if ALGORITHM == 1
|
||||
if(prev==NULL && tmp->next==NULL) {
|
||||
q->head = tmp;
|
||||
q->tail = tmp;
|
||||
} else if(prev==NULL) {
|
||||
q->head = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
} else if(tmp->next!=NULL) {
|
||||
prev->next = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
}
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
UNLOCK_RETURN(&q->m, -1); /* end me */
|
||||
return 0;
|
||||
|
||||
@ -551,11 +656,6 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own
|
||||
goto _end_write_file_queue;
|
||||
}
|
||||
|
||||
if (q->size + size > q->maxSize) { /* not enough space */
|
||||
errno = EFBIG;
|
||||
goto _end_write_file_queue;
|
||||
}
|
||||
|
||||
/* find the file */
|
||||
nodeT *tmp = q->head;
|
||||
while (tmp) {
|
||||
@ -570,6 +670,11 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own
|
||||
goto _end_write_file_queue;
|
||||
}
|
||||
|
||||
if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */
|
||||
errno = EFBIG;
|
||||
goto _end_write_file_queue;
|
||||
}
|
||||
|
||||
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||||
/* file is closed or the client does not hold the lock */
|
||||
errno = EPERM;
|
||||
@ -611,11 +716,6 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow
|
||||
goto _end_append_file_queue;
|
||||
}
|
||||
|
||||
if (q->size + size > q->maxSize) { /* not enough space */
|
||||
errno = EFBIG;
|
||||
goto _end_append_file_queue;
|
||||
}
|
||||
|
||||
/* find the file */
|
||||
nodeT *tmp = q->head;
|
||||
while (tmp) {
|
||||
@ -630,6 +730,11 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow
|
||||
goto _end_append_file_queue;
|
||||
}
|
||||
|
||||
if (q->size - tmp->data->size + size > q->maxSize) { /* not enough space */
|
||||
errno = EFBIG;
|
||||
goto _end_append_file_queue;
|
||||
}
|
||||
|
||||
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||||
/* file is closed or the client does not hold the lock */
|
||||
errno = EPERM;
|
||||
@ -738,11 +843,19 @@ fileT* find(queueT *q, char *filepath) {
|
||||
|
||||
fileT *res = NULL;
|
||||
nodeT *tmp = q->head;
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
nodeT *prev = NULL;
|
||||
#endif
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* trovato */
|
||||
break;
|
||||
}
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
prev = tmp;
|
||||
#endif
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@ -763,6 +876,24 @@ fileT* find(queueT *q, char *filepath) {
|
||||
goto _end_find_in_queue;
|
||||
}
|
||||
|
||||
/* if LRU put the file at the end */
|
||||
#if ALGORITHM == 1
|
||||
if(prev==NULL && tmp->next==NULL) {
|
||||
q->head = tmp;
|
||||
q->tail = tmp;
|
||||
} else if(prev==NULL) {
|
||||
q->head = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
} else if(tmp->next!=NULL) {
|
||||
prev->next = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
}
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||
return res;
|
||||
|
||||
@ -812,6 +943,14 @@ fileT ** request(queueT *q, int n) {
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* if LRU put the files at the end */
|
||||
#if ALGORITHM == 1
|
||||
q->tail->next = q->head;
|
||||
q->head = tmp->next;
|
||||
tmp->next = NULL;
|
||||
q->tail = tmp;
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
UNLOCK_RETURN(&q->m, NULL); /* end me */
|
||||
return returnList;
|
||||
|
||||
@ -835,17 +974,43 @@ int searchFile(queueT *q, char *filepath) {
|
||||
goto _end_search_file_in_queue;
|
||||
|
||||
nodeT *tmp = q->head;
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
nodeT *prev = NULL;
|
||||
#endif
|
||||
|
||||
while (tmp) {
|
||||
if (strcmp(filepath, (tmp->data)->filepath) == 0) { /* found */
|
||||
break;
|
||||
}
|
||||
/* if LRU keep track of previous */
|
||||
#if ALGORITHM == 1
|
||||
prev = tmp;
|
||||
#endif
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if(!tmp)
|
||||
goto _end_search_file_in_queue;
|
||||
|
||||
/* if LRU put the file at the end */
|
||||
#if ALGORITHM == 1
|
||||
if(prev==NULL && tmp->next==NULL) {
|
||||
q->head = tmp;
|
||||
q->tail = tmp;
|
||||
} else if(prev==NULL) {
|
||||
q->head = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
} else if(tmp->next!=NULL) {
|
||||
prev->next = tmp->next;
|
||||
q->tail->next = tmp;
|
||||
q->tail = tmp;
|
||||
tmp->next = NULL;
|
||||
}
|
||||
#endif /* ALGORITHM == 1 */
|
||||
|
||||
UNLOCK_RETURN(&q->m, 0); /* end me */
|
||||
return 1;
|
||||
|
||||
@ -897,6 +1062,9 @@ void destroyQueue(queueT *q) {
|
||||
if (errno) {
|
||||
perror("destroyQueue: voidDequeue");
|
||||
}
|
||||
if(q->head == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&q->m);
|
||||
|
||||
@ -7,6 +7,12 @@
|
||||
|
||||
#include "conn.h"
|
||||
|
||||
/* Algoritmo che viene usato per il rimpiazzo dei dati:
|
||||
se = 0 -> FIFO
|
||||
se = 1 -> LRU
|
||||
*/
|
||||
#define ALGORITHM 1
|
||||
|
||||
/* struttura dati per gestire i file in memoria principale */
|
||||
typedef struct {
|
||||
char *filepath; /* path assoluto del file */
|
||||
|
||||
Reference in New Issue
Block a user