|
|
|
|
@ -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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (q->head == NULL) { /* queue becomes empty */
|
|
|
|
|
q->tail = NULL;
|
|
|
|
|
break; /* we eliminated everything so we must have enought space */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|