2015-03-17 07:21:42 +00:00
|
|
|
#include "mm.h"
|
2015-03-17 01:51:00 +00:00
|
|
|
#include "linked_list.h"
|
|
|
|
|
|
|
|
//internal
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* NATIVE64 _linked_list_get_by_index(linked_list_node *head, int index)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
if(index <= 0 || head == NULL)
|
|
|
|
return head;
|
|
|
|
head = head->next;
|
|
|
|
index--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* NATIVE64 _linked_list_get_by_element(linked_list_node *head, void *data, int(*compare)(int *, int *))
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
if(head == NULL || compare(data,head->data) == 0)
|
|
|
|
return head;
|
|
|
|
head = head->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* NATIVE64 _linked_list_create_node()
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = (linked_list_node*)kmalloc(sizeof(linked_list_node));
|
2015-03-17 01:51:00 +00:00
|
|
|
node->data = NULL;
|
|
|
|
node->prev = NULL;
|
|
|
|
node->next = NULL;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 _linked_list_delete_node(linked_list *list, linked_list_node *node)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list != NULL && node != NULL)
|
|
|
|
{
|
|
|
|
//check if itself is head
|
|
|
|
if(list->head == node)
|
|
|
|
{
|
|
|
|
list->head = node->next;
|
|
|
|
}
|
|
|
|
//check if itself is tail
|
|
|
|
if(list->tail == node)
|
|
|
|
{
|
|
|
|
list->tail = node->prev;
|
|
|
|
}
|
|
|
|
if (node->prev != NULL)
|
|
|
|
node->prev->next = node->next;
|
|
|
|
if (node->next != NULL)
|
|
|
|
node->next->prev = node->prev;
|
|
|
|
list->size--;
|
2015-03-17 07:21:42 +00:00
|
|
|
kfree(node);
|
2015-03-17 01:51:00 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//interface
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list* NATIVE64 linked_list_create()
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list* list = (linked_list*)kmalloc(sizeof(linked_list));
|
2015-03-17 01:51:00 +00:00
|
|
|
list->size = 0;
|
|
|
|
list->tail = NULL;
|
|
|
|
list->head = NULL;
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_free(linked_list* list, void(*delete_data)(void*))
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL)
|
|
|
|
return;
|
|
|
|
linked_list_node* head = list->head;
|
|
|
|
while(head != NULL)
|
|
|
|
{
|
|
|
|
linked_list_node* temp = head;
|
|
|
|
head = head->next;
|
|
|
|
if(delete_data != NULL)
|
|
|
|
delete_data(temp->data);
|
2015-03-17 07:21:42 +00:00
|
|
|
kfree(temp);
|
2015-03-17 01:51:00 +00:00
|
|
|
}
|
2015-03-17 07:21:42 +00:00
|
|
|
kfree(list);
|
2015-03-17 01:51:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_insert(linked_list * list, void* data)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL)
|
|
|
|
return;
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = _linked_list_create_node();
|
2015-03-17 01:51:00 +00:00
|
|
|
node->data = data;
|
|
|
|
if(list->tail != NULL)
|
|
|
|
{
|
|
|
|
//already elements in the list
|
|
|
|
//guaranteed that list->next == NULL
|
|
|
|
node->prev = list->tail;
|
|
|
|
list->tail->next = node;
|
|
|
|
list->tail = node;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//no element case
|
|
|
|
list->tail = node;
|
|
|
|
list->head = node;
|
|
|
|
}
|
|
|
|
list->size++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_insert_at(linked_list * list, int position, void* data)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list != NULL && position >= 0 && position <= list->size)
|
|
|
|
{
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* target = _linked_list_get_by_index(list->head, position);
|
2015-03-17 01:51:00 +00:00
|
|
|
if(target == NULL)
|
|
|
|
{
|
|
|
|
//tail case
|
|
|
|
linked_list_insert(list, data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//head or normal case
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = _linked_list_create_node();
|
2015-03-17 01:51:00 +00:00
|
|
|
node->data = data;
|
|
|
|
if (list->head == target) {
|
|
|
|
list->head = node;
|
|
|
|
}
|
|
|
|
node->prev = target->prev;
|
|
|
|
node->next = target;
|
|
|
|
if (target->prev != NULL)
|
|
|
|
target->prev->next = node;
|
|
|
|
target->prev = node;
|
|
|
|
list->size++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void* NATIVE64 linked_list_get(linked_list * list, int index)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL || list->head == NULL || index < 0 || list->size <= index)
|
|
|
|
return NULL;
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = _linked_list_get_by_index(list->head, index);
|
2015-03-17 01:51:00 +00:00
|
|
|
return node == NULL ? NULL : node->data;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_delete(linked_list * list, void* data, int(*compare)(int*,int*))
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL || list->head == NULL || compare == NULL)
|
|
|
|
return;
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = _linked_list_get_by_element(list->head, data, compare);
|
|
|
|
_linked_list_delete_node(list, node);
|
2015-03-17 01:51:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_delete_at(linked_list * list, int index)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL || list->head == NULL || index < 0 || list->size <= index)
|
|
|
|
return;
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_node* node = _linked_list_get_by_index(list->head, index);
|
|
|
|
_linked_list_delete_node(list, node);
|
2015-03-17 01:51:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterator
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_iterator* NATIVE64 linked_list_create_iterator(linked_list* list)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
if(list == NULL)
|
|
|
|
return NULL;
|
2015-03-17 07:21:42 +00:00
|
|
|
linked_list_iterator* it = (linked_list_iterator*)kmalloc(sizeof(linked_list_iterator));
|
2015-03-17 01:51:00 +00:00
|
|
|
it->current = list->head;
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_delete_iterator(linked_list_iterator* it)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
2015-03-17 07:21:42 +00:00
|
|
|
kfree(it);
|
2015-03-17 01:51:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_prev(linked_list_iterator* it)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
it->current = it->current->prev;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-17 07:21:42 +00:00
|
|
|
void NATIVE64 linked_list_next(linked_list_iterator* it)
|
2015-03-17 01:51:00 +00:00
|
|
|
{
|
|
|
|
it->current = it->current->next;
|
|
|
|
return;
|
|
|
|
}
|