Changed the interface for linked list and avl tree to a much more flexible one. The previous one was utter crap..
This commit is contained in:
parent
ab103126b6
commit
7db4e9cf35
|
@ -0,0 +1,84 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include "avl_tree.h"
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
avl_tree_node node;
|
||||
int val;
|
||||
} int_node;
|
||||
|
||||
int compare(void* a, void* b)
|
||||
{
|
||||
int_node* aa = (int_node*)a;
|
||||
int_node* bb = (int_node*)b;
|
||||
if(aa->val > bb->val)
|
||||
return 1;
|
||||
else if(aa->val < bb->val)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void in_order_print(avl_tree_node *tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return;
|
||||
avl_tree_node* node = avl_tree_node_largest(tree);
|
||||
while(node != NULL)
|
||||
{
|
||||
printf("%d ", ((int_node*)node)->val);
|
||||
node = avl_tree_node_prev(node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int_node* create_int_node(int val)
|
||||
{
|
||||
int_node* node = (int_node*)malloc(sizeof(int_node));
|
||||
avl_tree_node_init(&node->node);
|
||||
node->val = val;
|
||||
return node;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int_node* val[1000];
|
||||
srand((unsigned int)time(NULL));
|
||||
avl_tree* avlTree = (avl_tree*)malloc(sizeof(avl_tree));
|
||||
avl_tree_init(avlTree);
|
||||
//test INSERT general
|
||||
int i = 0;
|
||||
for(i = 0; i < 1000; i++)
|
||||
{
|
||||
val[i] = create_int_node(rand()%10000);
|
||||
avl_tree_insert(avlTree,(avl_tree_node*)val[i],compare);
|
||||
assert(avl_tree_node_test(avlTree->root,compare));
|
||||
}
|
||||
//test Delete general
|
||||
for(i = 0; i < 1000; i++)
|
||||
{
|
||||
avl_tree_delete(avlTree,val[i],compare);
|
||||
assert(avl_tree_node_test(avlTree->root,compare));
|
||||
free(val[i]);
|
||||
}
|
||||
|
||||
//test delete visualized
|
||||
for(i = 0; i < 20; i++)
|
||||
{
|
||||
val[i] = create_int_node(rand()%2000);
|
||||
avl_tree_insert(avlTree,(avl_tree_node*)val[i],compare);
|
||||
assert(avl_tree_node_test(avlTree->root,compare));
|
||||
}
|
||||
in_order_print(avlTree->root);
|
||||
for(i = 0; i < 20; i++)
|
||||
{
|
||||
avl_tree_delete(avlTree,(avl_tree_node*)val[i],compare);
|
||||
printf("\nDeleting: %d\n",val[i]->val);
|
||||
in_order_print(avlTree->root);
|
||||
assert(avl_tree_node_test(avlTree->root,compare));
|
||||
free(val[i]);
|
||||
}
|
||||
free(avlTree);
|
||||
return 0;
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "linked_list.h"
|
||||
|
||||
void print_list(linked_list* list)
|
||||
{
|
||||
linked_list_iterator* it = linked_list_create_iterator(list);
|
||||
it->current = list->tail;
|
||||
while(it->current)
|
||||
{
|
||||
printf("%lu ", (unsigned long)it->current->data);
|
||||
linked_list_prev(it);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void insert_test(void)
|
||||
{
|
||||
printf("insert test\n");
|
||||
linked_list* list;
|
||||
//empty list at test
|
||||
list = linked_list_create();
|
||||
linked_list_insert_at(list,0,(void*)2);
|
||||
assert(list->size == 1 && list->head == list->tail && (int)list->head->data == 2);
|
||||
print_list(list);
|
||||
|
||||
//tail test
|
||||
linked_list_insert_at(list,1,(void*)3);
|
||||
assert(list->size == 2 && (int)list->tail->data == 3);
|
||||
print_list(list);
|
||||
|
||||
//head test
|
||||
linked_list_insert_at(list,0,(void*)1);
|
||||
assert(list->size == 3 && (int)list->head->data == 1);
|
||||
print_list(list);
|
||||
|
||||
//invalid index test
|
||||
linked_list_insert_at(list,4,(void*)1);
|
||||
assert(list->size == 3 && (int)list->head->data == 1 && (int)list->tail->data == 3);
|
||||
print_list(list);
|
||||
|
||||
//normal test
|
||||
linked_list_insert_at(list,1,(void*)5);
|
||||
assert(list->size == 4 && (int)list->head->next->data == 5 && (int)list->head->next->next->data == 2);
|
||||
print_list(list);
|
||||
|
||||
linked_list_free(list,NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void delete_test(void)
|
||||
{
|
||||
printf("delete test\n");
|
||||
linked_list* list;
|
||||
//empty list at test
|
||||
list = linked_list_create();
|
||||
linked_list_insert(list,(void*)1);
|
||||
linked_list_insert(list,(void*)2);
|
||||
linked_list_insert(list,(void*)3);
|
||||
linked_list_insert(list,(void*)4);
|
||||
linked_list_insert(list,(void*)5);
|
||||
|
||||
//head test
|
||||
linked_list_delete_at(list,0);
|
||||
assert(list->size == 4 && (int)list->head->data == 2);
|
||||
print_list(list);
|
||||
|
||||
//tail test
|
||||
linked_list_delete_at(list,list->size-1);
|
||||
assert(list->size == 3 && (int)list->tail->data == 4);
|
||||
print_list(list);
|
||||
|
||||
//normal test
|
||||
linked_list_delete_at(list,1);
|
||||
assert(list->size == 2 && (int)list->head->data == 2 && (int)list->head->next->data==4);
|
||||
print_list(list);
|
||||
|
||||
//invalid index test
|
||||
linked_list_delete_at(list,2);
|
||||
assert(list->size == 2 && (int)list->head->data == 2 && (int)list->head->next->data==4);
|
||||
print_list(list);
|
||||
|
||||
//delete last test
|
||||
linked_list_delete_at(list,0);
|
||||
linked_list_delete_at(list,0);
|
||||
assert(list->size == 0 && list->head == NULL && list->tail == NULL);
|
||||
|
||||
linked_list_free(list,NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
insert_test();
|
||||
delete_test();
|
||||
return 0;
|
||||
}
|
|
@ -1,23 +1,21 @@
|
|||
#include "kdef.h"
|
||||
#include "mm.h"
|
||||
#include "avl_tree.h"
|
||||
|
||||
#define MAX(a, b) (((a) > (b) ? (a) : (b)))
|
||||
|
||||
// internal
|
||||
int NATIVE64 _avl_tree_get_height(avl_tree_node *node)
|
||||
int NATIVE64 _avl_tree_node_get_height(avl_tree_node *node)
|
||||
{
|
||||
return node == NULL ? -1 : node->height;
|
||||
}
|
||||
|
||||
int NATIVE64 _avl_tree_get_balance_factor(avl_tree_node *node)
|
||||
int NATIVE64 _avl_tree_node_get_balance_factor(avl_tree_node *node)
|
||||
{
|
||||
if (node == NULL)
|
||||
return 0;
|
||||
return _avl_tree_get_height(node->left) - _avl_tree_get_height(node->right);
|
||||
return _avl_tree_node_get_height(node->left) - _avl_tree_node_get_height(node->right);
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_right_rotate(avl_tree_node *root)
|
||||
avl_tree_node * NATIVE64 _avl_tree_node_right_rotate(avl_tree_node *root)
|
||||
{
|
||||
avl_tree_node *left_children = root->left;
|
||||
//adjust parents first
|
||||
|
@ -29,12 +27,12 @@ avl_tree_node * NATIVE64 _avl_tree_right_rotate(avl_tree_node *root)
|
|||
root->left = root->left->right;
|
||||
left_children->right = root;
|
||||
//adjust height
|
||||
root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1;
|
||||
left_children->height = MAX(_avl_tree_get_height(left_children->left), _avl_tree_get_height(left_children->right)) + 1;
|
||||
root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
||||
left_children->height = MAX(_avl_tree_node_get_height(left_children->left), _avl_tree_node_get_height(left_children->right)) + 1;
|
||||
return left_children;
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_left_rotate(avl_tree_node *root)
|
||||
avl_tree_node * NATIVE64 _avl_tree_node_left_rotate(avl_tree_node *root)
|
||||
{
|
||||
avl_tree_node *right_children = root->right;
|
||||
//adjust parents
|
||||
|
@ -46,41 +44,41 @@ avl_tree_node * NATIVE64 _avl_tree_left_rotate(avl_tree_node *root)
|
|||
root->right = root->right->left;
|
||||
right_children->left = root;
|
||||
|
||||
root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1;
|
||||
right_children->height = MAX(_avl_tree_get_height(right_children->left), _avl_tree_get_height(right_children->right)) + 1;
|
||||
root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
||||
right_children->height = MAX(_avl_tree_node_get_height(right_children->left), _avl_tree_node_get_height(right_children->right)) + 1;
|
||||
return right_children;
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_balance_node(avl_tree_node *node)
|
||||
avl_tree_node * NATIVE64 _avl_tree_node_balance(avl_tree_node *node)
|
||||
{
|
||||
const int bf = _avl_tree_get_balance_factor(node);
|
||||
const int bf = _avl_tree_node_get_balance_factor(node);
|
||||
|
||||
if (bf > 1)
|
||||
{
|
||||
const int left_bf = _avl_tree_get_balance_factor(node->left);
|
||||
const int left_bf = _avl_tree_node_get_balance_factor(node->left);
|
||||
if (left_bf >= 0)
|
||||
//left left
|
||||
return _avl_tree_right_rotate(node);
|
||||
return _avl_tree_node_right_rotate(node);
|
||||
else
|
||||
{
|
||||
//left right
|
||||
node->left = _avl_tree_left_rotate(node->left);
|
||||
return _avl_tree_right_rotate(node);
|
||||
node->left = _avl_tree_node_left_rotate(node->left);
|
||||
return _avl_tree_node_right_rotate(node);
|
||||
}
|
||||
}
|
||||
else if (bf < -1)
|
||||
{
|
||||
const int right_bf = _avl_tree_get_balance_factor(node->right);
|
||||
const int right_bf = _avl_tree_node_get_balance_factor(node->right);
|
||||
if (right_bf <= 0)
|
||||
{
|
||||
// right right
|
||||
return _avl_tree_left_rotate(node);
|
||||
return _avl_tree_node_left_rotate(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
// right left
|
||||
node->right = _avl_tree_right_rotate(node->right);
|
||||
return _avl_tree_left_rotate(node);
|
||||
node->right = _avl_tree_node_right_rotate(node->right);
|
||||
return _avl_tree_node_left_rotate(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -88,87 +86,166 @@ avl_tree_node * NATIVE64 _avl_tree_balance_node(avl_tree_node *node)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void * NATIVE64 _avl_tree_search(avl_tree_node *root, void *data, int(*compare)(void *, void *))
|
||||
avl_tree_node * NATIVE64 _avl_tree_node_insert(avl_tree_node *root, avl_tree_node *node, int(*compare)(void *, void *), avl_tree_node *parent)
|
||||
{
|
||||
if(root == NULL)
|
||||
return NULL;
|
||||
const int comp = compare(root->data, data);
|
||||
if (comp < 0)
|
||||
return _avl_tree_search(root->right, data, compare);
|
||||
else if (comp == 0)
|
||||
return root->data;
|
||||
else
|
||||
return _avl_tree_search(root->left, data, compare);
|
||||
}
|
||||
|
||||
void * NATIVE64 avl_tree_search(avl_tree *root, void *data, int(*compare)(void *, void *))
|
||||
{
|
||||
if(root == NULL || data == NULL)
|
||||
return NULL;
|
||||
return _avl_tree_search(root->root, data, compare);
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_create_node()
|
||||
{
|
||||
avl_tree_node *tree = (avl_tree_node *) (kmalloc(sizeof(avl_tree_node)));
|
||||
tree->parent = NULL;
|
||||
tree->data = NULL;
|
||||
tree->right = NULL;
|
||||
tree->left = NULL;
|
||||
tree->height = 0;
|
||||
return tree;
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_insert(avl_tree_node *root, void *data, int(*compare)(void *, void *), avl_tree_node *parent)
|
||||
{
|
||||
if (data == NULL)
|
||||
if (node == NULL)
|
||||
return root;
|
||||
if (root == NULL)
|
||||
{
|
||||
avl_tree_node *tree = _avl_tree_create_node();
|
||||
tree->data = data;
|
||||
tree->parent = parent;
|
||||
return tree;
|
||||
node->parent = parent;
|
||||
return node;
|
||||
}
|
||||
|
||||
const int comp = compare(root->data, data);
|
||||
const int comp = compare(root, node);
|
||||
if (comp < 0)
|
||||
{
|
||||
root->right = _avl_tree_insert(root->right, data, compare, root);
|
||||
}
|
||||
root->right = _avl_tree_node_insert(root->right, node, compare, root);
|
||||
else if (comp == 0)
|
||||
return root;
|
||||
else
|
||||
root->left = _avl_tree_insert(root->left, data, compare, root);
|
||||
root->left = _avl_tree_node_insert(root->left, node, compare, root);
|
||||
|
||||
root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1;
|
||||
root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
||||
|
||||
return _avl_tree_balance_node(root);
|
||||
return _avl_tree_node_balance(root);
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *))
|
||||
void _swap_nodes(avl_tree_node *node1, avl_tree_node *node2)
|
||||
{
|
||||
if(tree != NULL && data != NULL && compare != NULL)
|
||||
if (node1 == NULL || node2 == NULL)
|
||||
return;
|
||||
avl_tree_node *parent = NULL;
|
||||
avl_tree_node *child = NULL;
|
||||
avl_tree_node *temp = NULL;
|
||||
//swap node but does not change anything else other than node1,node2
|
||||
if (node1->parent != NULL && node1->parent == node2)
|
||||
{
|
||||
if(avl_tree_search(tree, data, compare) == NULL)
|
||||
parent = node2;
|
||||
child = node1;
|
||||
}
|
||||
else if (node2->parent != NULL && node2->parent == node1)
|
||||
{
|
||||
parent = node1;
|
||||
child = node2;
|
||||
}
|
||||
|
||||
if (parent != NULL && child != NULL)
|
||||
{
|
||||
//connected case
|
||||
if(parent->parent != NULL)
|
||||
{
|
||||
tree->root = _avl_tree_insert(tree->root, data, compare, NULL);
|
||||
tree->size++;
|
||||
if(parent->parent->left == parent)
|
||||
parent->parent->left = child;
|
||||
else
|
||||
parent->parent->right = child;
|
||||
}
|
||||
//update left/right for parent
|
||||
if(parent->left != NULL && child != parent->left)
|
||||
{
|
||||
parent->left->parent = child;
|
||||
}
|
||||
if(parent->right != NULL && child != parent->right)
|
||||
{
|
||||
parent->right->parent = child;
|
||||
}
|
||||
//update left/right for children
|
||||
if(child->left != NULL)
|
||||
child->left->parent = parent;
|
||||
if(child->right != NULL)
|
||||
child->right->parent = parent;
|
||||
|
||||
child->parent = parent->parent;
|
||||
parent->parent = child;
|
||||
if (child == parent->left)
|
||||
{
|
||||
// parent
|
||||
// / \
|
||||
// children
|
||||
parent->left = child->left;
|
||||
child->left = parent;
|
||||
|
||||
temp = parent->right;
|
||||
parent->right = child->right;
|
||||
child->right = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// parent
|
||||
// / \
|
||||
// children
|
||||
parent->right = child->right;
|
||||
child->right = parent;
|
||||
|
||||
temp = parent->left;
|
||||
parent->left = child->left;
|
||||
child->left = temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//not connected case
|
||||
//adjust all the nodes other than node1,node2
|
||||
if(node1->left != NULL)
|
||||
node1->left->parent = node2;
|
||||
if(node1->right != NULL)
|
||||
node1->right->parent = node2;
|
||||
|
||||
if(node2->left != NULL)
|
||||
node2->left->parent = node1;
|
||||
if(node2->right != NULL)
|
||||
node2->right->parent = node1;
|
||||
|
||||
if(node1->parent != NULL)
|
||||
{
|
||||
if(node1->parent->left == node1)
|
||||
node1->parent->left = node2;
|
||||
else
|
||||
node1->parent->right = node2;
|
||||
}
|
||||
|
||||
if(node2->parent != NULL)
|
||||
{
|
||||
if(node2->parent->left == node2)
|
||||
node2->parent->left = node1;
|
||||
else
|
||||
node2->parent->right = node1;
|
||||
}
|
||||
|
||||
//adjust node1,node2
|
||||
temp = node1->parent;
|
||||
node1->parent = node2->parent;
|
||||
node2->parent = temp;
|
||||
|
||||
temp = node1->left;
|
||||
node1->left = node2->left;
|
||||
node2->left = temp;
|
||||
|
||||
temp = node1->right;
|
||||
node1->right = node2->right;
|
||||
node2->right = temp;
|
||||
}
|
||||
|
||||
//swap height
|
||||
int height = node1->height;
|
||||
node1->height = node2->height;
|
||||
node2->height = height;
|
||||
return;
|
||||
}
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_delete(avl_tree_node *root, void *data, int (*compare)(void *, void *))
|
||||
//Interface
|
||||
avl_tree_node* NATIVE64 avl_tree_node_insert(avl_tree_node* root, avl_tree_node* node, int(*compare)(void*,void*))
|
||||
{
|
||||
if (root == NULL || data == NULL)
|
||||
return _avl_tree_node_insert(root, node, compare, NULL);
|
||||
}
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_delete(avl_tree_node* root, avl_tree_node* node, int (*compare)(void *, void *))
|
||||
{
|
||||
if (root == NULL || node == NULL)
|
||||
return root;
|
||||
const int comp = compare(root->data, data);
|
||||
const int comp = compare(root, node);
|
||||
if (comp < 0)
|
||||
root->right = _avl_tree_delete(root->right, data, compare);
|
||||
root->right = avl_tree_node_delete(root->right, node, compare);
|
||||
else if(comp > 0)
|
||||
root->left = _avl_tree_delete(root->left, data, compare);
|
||||
root->left = avl_tree_node_delete(root->left, node, compare);
|
||||
else
|
||||
{
|
||||
// node with only one child or no child
|
||||
|
@ -178,89 +255,64 @@ avl_tree_node * NATIVE64 _avl_tree_delete(avl_tree_node *root, void *data, int (
|
|||
|
||||
if(child == NULL)
|
||||
{ // 0 child
|
||||
//free(root);
|
||||
root = NULL;
|
||||
}
|
||||
else // 1 child
|
||||
{
|
||||
//copy content of temp to root except for the parent
|
||||
root->left = child->left;
|
||||
root->right = child->right;
|
||||
root->data = child->data;
|
||||
root->height = child->height;
|
||||
//free(child);
|
||||
child->parent = root->parent;
|
||||
root = child;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// node with two children: Get the inorder successor (smallest
|
||||
// in the right subtree)
|
||||
avl_tree_node *successor = root->right;
|
||||
while(successor->left != NULL)
|
||||
successor = successor->left;
|
||||
//swap fields
|
||||
_swap_nodes(successor,root);
|
||||
|
||||
avl_tree_node * temp = root->right;
|
||||
while(temp->left != NULL)
|
||||
temp = temp->left;
|
||||
// Detach the inorder successor
|
||||
successor->right = avl_tree_node_delete(successor->right, root, compare);
|
||||
|
||||
// Copy the inorder successor's data to this node
|
||||
root->data = temp->data;
|
||||
|
||||
// Delete the inorder successor
|
||||
root->right = _avl_tree_delete(root->right, temp->data, compare);
|
||||
root = successor;
|
||||
}
|
||||
}
|
||||
if (root == NULL)
|
||||
return root;
|
||||
root->height = MAX(_avl_tree_get_height(root->left), _avl_tree_get_height(root->right)) + 1;
|
||||
root = _avl_tree_balance_node(root);
|
||||
root->height = MAX(_avl_tree_node_get_height(root->left), _avl_tree_node_get_height(root->right)) + 1;
|
||||
root = _avl_tree_node_balance(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *))
|
||||
avl_tree_node* NATIVE64 avl_tree_node_search(avl_tree_node *root, avl_tree_node* node, int(*compare)(void *, void *))
|
||||
{
|
||||
if(tree != NULL && data != NULL && compare != NULL && tree->size != 0)
|
||||
if(root == NULL)
|
||||
return NULL;
|
||||
const int comp = compare(root, node);
|
||||
if (comp < 0)
|
||||
return avl_tree_node_search(root->right, node, compare);
|
||||
else if (comp == 0)
|
||||
return root;
|
||||
else
|
||||
return avl_tree_node_search(root->left, node, compare);
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_node_init(avl_tree_node* it)
|
||||
{
|
||||
if(it != NULL)
|
||||
{
|
||||
if(avl_tree_search(tree, data, compare) != NULL)
|
||||
{
|
||||
tree->root = _avl_tree_delete(tree->root, data, compare);
|
||||
tree->size--;
|
||||
}
|
||||
it->height = 0;
|
||||
it->left = NULL;
|
||||
it->right = NULL;
|
||||
it->parent = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 _avl_tree_free(avl_tree_node *root, void (*delete_data)(void *))
|
||||
{
|
||||
if(root != NULL)
|
||||
{
|
||||
_avl_tree_free(root->left, delete_data);
|
||||
_avl_tree_free(root->right, delete_data);
|
||||
if (delete_data != NULL)
|
||||
delete_data(root->data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_free(avl_tree *tree, void (*delete_data)(void *))
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
_avl_tree_free(tree->root, delete_data);
|
||||
kfree(tree);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
avl_tree * NATIVE64 avl_tree_create()
|
||||
{
|
||||
avl_tree* new_tree = kmalloc(sizeof(avl_tree));
|
||||
new_tree->root = NULL;
|
||||
new_tree->size = 0;
|
||||
return new_tree;
|
||||
}
|
||||
|
||||
|
||||
//iterator
|
||||
|
||||
avl_tree_node * NATIVE64 _avl_tree_smallest(avl_tree_node *root)
|
||||
avl_tree_node * NATIVE64 avl_tree_node_smallest(avl_tree_node *root)
|
||||
{
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
|
@ -269,89 +321,135 @@ avl_tree_node * NATIVE64 _avl_tree_smallest(avl_tree_node *root)
|
|||
return root;
|
||||
}
|
||||
|
||||
avl_tree_iterator* NATIVE64 avl_tree_create_iterator(avl_tree *tree)
|
||||
avl_tree_node * NATIVE64 avl_tree_node_largest(avl_tree_node *root)
|
||||
{
|
||||
if(tree == NULL)
|
||||
if (root == NULL)
|
||||
return NULL;
|
||||
avl_tree_iterator* it = (avl_tree_iterator*)kmalloc(sizeof(avl_tree_iterator));
|
||||
it->current = _avl_tree_smallest(tree->root);
|
||||
return it;
|
||||
while (root->right != NULL)
|
||||
root = root->right;
|
||||
return root;
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_next(avl_tree_iterator *it)
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_next(avl_tree_node *it)
|
||||
{
|
||||
if (it == NULL || it->current == NULL)
|
||||
return;
|
||||
avl_tree_node* root = it->current;
|
||||
if (it == NULL)
|
||||
return NULL;
|
||||
avl_tree_node* root = it;
|
||||
if (root->right != NULL)
|
||||
{
|
||||
root = root->right;
|
||||
while (root->left != NULL)
|
||||
{
|
||||
root = root->left;
|
||||
}
|
||||
it->current = root;
|
||||
return;
|
||||
return root;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (root->parent != NULL)
|
||||
{
|
||||
if (root->parent->left == root)
|
||||
{
|
||||
it->current = root->parent;
|
||||
return;
|
||||
}
|
||||
return root->parent;
|
||||
root = root->parent;
|
||||
}
|
||||
it->current = NULL;
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_prev(avl_tree_iterator *it)
|
||||
avl_tree_node* NATIVE64 avl_tree_node_prev(avl_tree_node *it)
|
||||
{
|
||||
if (it == NULL || it->current == NULL)
|
||||
return;
|
||||
avl_tree_node* root = it->current;
|
||||
if (it == NULL)
|
||||
return NULL;
|
||||
avl_tree_node* root = it;
|
||||
if (root->left != NULL)
|
||||
{
|
||||
root = root->left;
|
||||
while (root->right != NULL)
|
||||
{
|
||||
root = root->right;
|
||||
}
|
||||
it->current = root;
|
||||
return root;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (root->parent != NULL)
|
||||
{
|
||||
if (root->parent->right == root)
|
||||
{
|
||||
it->current = root->parent;
|
||||
}
|
||||
return root->parent;
|
||||
root = root->parent;
|
||||
}
|
||||
it->current = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
avl_tree_node* avl_tree_search(avl_tree *tree, avl_tree_node* node, int (*compare)(void *, void *))
|
||||
{
|
||||
return avl_tree_node_search(tree->root,node,compare);
|
||||
}
|
||||
|
||||
|
||||
void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *))
|
||||
{
|
||||
if(tree != NULL && data != NULL && compare != NULL)
|
||||
{
|
||||
if(avl_tree_search(tree, data, compare) == NULL)
|
||||
{
|
||||
tree->root = _avl_tree_node_insert(tree->root, data, compare, NULL);
|
||||
tree->size++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *))
|
||||
{
|
||||
if(tree != NULL && data != NULL && compare != NULL && tree->size != 0)
|
||||
{
|
||||
if(avl_tree_search(tree, data, compare) != NULL)
|
||||
{
|
||||
tree->root = avl_tree_node_delete(tree->root, data, compare);
|
||||
tree->size--;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 avl_tree_init(avl_tree* tree)
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
tree->root = NULL;
|
||||
tree->size = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// TESTS
|
||||
|
||||
int NATIVE64 avl_tree_test_calculate_height(avl_tree_node *tree)
|
||||
int NATIVE64 avl_tree_node_calculate_height(avl_tree_node *tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return -1;
|
||||
return MAX(avl_tree_test_calculate_height(tree->left), avl_tree_test_calculate_height(tree->right)) + 1;
|
||||
return MAX(avl_tree_node_calculate_height(tree->left), avl_tree_node_calculate_height(tree->right)) + 1;
|
||||
}
|
||||
|
||||
int NATIVE64 avl_tree_test(avl_tree_node *tree)
|
||||
int NATIVE64 avl_tree_node_test(avl_tree_node *tree, int (*compare)(void*,void*))
|
||||
{
|
||||
if (tree == NULL)
|
||||
return 1;
|
||||
if (_avl_tree_get_balance_factor(tree) < -1 || _avl_tree_get_balance_factor(tree) > 1 || avl_tree_test_calculate_height(tree) != tree->height)
|
||||
if (_avl_tree_node_get_balance_factor(tree) < -1 || _avl_tree_node_get_balance_factor(tree) > 1 || avl_tree_node_calculate_height(tree) != tree->height)
|
||||
return 0;
|
||||
return avl_tree_test(tree->left) && avl_tree_test(tree->right);
|
||||
if(tree->left != NULL)
|
||||
{
|
||||
if(tree->left->parent != tree)
|
||||
return 0;
|
||||
}
|
||||
if(tree->right != NULL)
|
||||
{
|
||||
if(tree->right->parent != tree)
|
||||
return 0;
|
||||
}
|
||||
if(compare != NULL)
|
||||
{
|
||||
if((tree->right != NULL && compare(tree,tree->right) > 0) || (tree->left != NULL && compare(tree,tree->left) < 0))
|
||||
return 0;
|
||||
}
|
||||
return avl_tree_node_test(tree->left,compare) && avl_tree_node_test(tree->right,compare);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ typedef struct __attribute__((packed)) _avl_tree_node
|
|||
struct _avl_tree_node * right;
|
||||
struct _avl_tree_node * parent;
|
||||
int height;
|
||||
void *data;
|
||||
} avl_tree_node;
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
|
@ -17,29 +16,36 @@ typedef struct __attribute__((packed))
|
|||
int size;
|
||||
} avl_tree;
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
avl_tree_node * current;
|
||||
} avl_tree_iterator;
|
||||
avl_tree_node* NATIVE64 avl_tree_node_insert(avl_tree_node* root, avl_tree_node* node, int(*compare)(void*,void*));
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_delete(avl_tree_node* root, avl_tree_node* node, int (*compare)(void *, void *));
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_search(avl_tree_node *root, avl_tree_node* node, int(*compare)(void *, void *));
|
||||
|
||||
void NATIVE64 avl_tree_node_init(avl_tree_node* it);
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_next(avl_tree_node *it);
|
||||
|
||||
avl_tree_node* NATIVE64 avl_tree_node_prev(avl_tree_node *it);
|
||||
|
||||
avl_tree_node * NATIVE64 avl_tree_node_smallest(avl_tree_node *root);
|
||||
|
||||
avl_tree_node * NATIVE64 avl_tree_node_largest(avl_tree_node *root);
|
||||
|
||||
|
||||
|
||||
avl_tree_node* avl_tree_search(avl_tree *tree, avl_tree_node* node, int (*compare)(void *, void *));
|
||||
|
||||
void NATIVE64 avl_tree_insert(avl_tree *tree, void *data, int (*compare)(void *, void *));
|
||||
|
||||
void NATIVE64 avl_tree_delete(avl_tree *tree, void *data, int (*compare)(void *, void *));
|
||||
|
||||
void NATIVE64 avl_tree_free(avl_tree *tree, void (*delete_data)(void *));
|
||||
void NATIVE64 avl_tree_init(avl_tree* tree);
|
||||
|
||||
void NATIVE64 *avl_tree_search(avl_tree *tree, void *data, int(*compare)(void *, void *));
|
||||
// TESTS
|
||||
|
||||
avl_tree * NATIVE64 avl_tree_create();
|
||||
int NATIVE64 avl_tree_node_calculate_height(avl_tree_node *tree);
|
||||
|
||||
avl_tree_iterator* NATIVE64 avl_tree_create_iterator(avl_tree *tree);
|
||||
|
||||
void NATIVE64 avl_tree_next(avl_tree_iterator *it);
|
||||
|
||||
void NATIVE64 avl_tree_prev(avl_tree_iterator *it);
|
||||
|
||||
int NATIVE64 avl_tree_test_calculate_height(avl_tree_node *tree);
|
||||
|
||||
int NATIVE64 avl_tree_test(avl_tree_node *tree);
|
||||
int NATIVE64 avl_tree_node_test(avl_tree_node *tree, int(*compare)(void *, void *));
|
||||
|
||||
#endif
|
|
@ -3,6 +3,8 @@
|
|||
#include "print.h"
|
||||
#include "mm.h"
|
||||
#include "multiboot.h"
|
||||
#include "linked_list.h"
|
||||
|
||||
uint8_t g_gdt[8*9];
|
||||
gdt_ptr_t g_gdt_ptr;
|
||||
extern uint64_t text_pos;
|
||||
|
@ -26,12 +28,13 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info)
|
|||
write_segment_descriptor((void *) &g_gdt[48], 0, 0xFFFFF, SEG_DPL_0 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_DATA_RW);
|
||||
write_segment_descriptor((void *) &g_gdt[56], 0, 0xFFFFF, SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_CODE_X);
|
||||
write_segment_descriptor((void *) &g_gdt[64], 0, 0xFFFFF, SEG_DPL_3 | SEG_GRANULARITY | SEG_CODE_DATA | SEG_PRESENT | SEG_32_BITS | SEG_TYPE_DATA_RW);
|
||||
|
||||
g_gdt_ptr.base = (uint64_t)g_gdt;
|
||||
g_gdt_ptr.limit = 8*9-1;
|
||||
flush_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(2, 0));
|
||||
kprintf("Done.\n\n");
|
||||
|
||||
linked_list* mm_list = (linked_list*)kmalloc(sizeof(linked_list));
|
||||
linked_list_init(mm_list);
|
||||
kprintf("allocated:0x%x\n",(uint64_t)mm_list);
|
||||
kprintf("*Checking memory information...\n");
|
||||
if(multiboot_info->flags & (1 << 6))
|
||||
{
|
||||
|
@ -40,7 +43,7 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info)
|
|||
kprintf("BaseAddr - Length - Type\n");
|
||||
uint64_t total_available_mem = 0;
|
||||
uint64_t total_reserved_mem = 0;
|
||||
for (uint64_t i = 0; i < mem_map_size; i++)
|
||||
for (int i = 0; i < mem_map_size; i++)
|
||||
{
|
||||
kprintf("0x%X - 0x%X - 0x%x\n", (mem_map + i)->addr, (mem_map + i)->len, (mem_map + i)->type);
|
||||
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
|
||||
|
@ -49,11 +52,21 @@ void NATIVE64 kmain(multiboot_info_t *multiboot_info)
|
|||
}
|
||||
else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||
{
|
||||
phy_mem_info* mm_info = kmalloc(sizeof(phy_mem_info));
|
||||
linked_list_node_init(&mm_info->node);
|
||||
mm_info->base = (mem_map+i)->addr;
|
||||
mm_info->limit = (mem_map+i)->len;
|
||||
linked_list_add(mm_list,(linked_list_node*)mm_info);
|
||||
total_available_mem += (mem_map + i)->len;
|
||||
}
|
||||
}
|
||||
kprintf("Total available memory: %uB, %uKB, %uMB.\n", total_available_mem, total_available_mem / 1024, total_available_mem / 1024 / 1024);
|
||||
kprintf("Total reserved memory: %uB, %uKB, %uMB.\n\n", total_reserved_mem, total_reserved_mem / 1024, total_reserved_mem / 1024 / 1024);
|
||||
for(int i = 0; i < mm_list->size; i++)
|
||||
{
|
||||
phy_mem_info* mem_info = (phy_mem_info*)linked_list_get(mm_list,i);
|
||||
kprintf("0x%X - 0x%X", mem_info->base, mem_info->limit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "int.h"
|
|
@ -1,3 +0,0 @@
|
|||
#ifndef _INT_H_
|
||||
#define _INT_H_
|
||||
#endif
|
|
@ -1,193 +1,156 @@
|
|||
#include "mm.h"
|
||||
#include "kdef.h"
|
||||
#include "linked_list.h"
|
||||
|
||||
//internal
|
||||
|
||||
linked_list_node* NATIVE64 _linked_list_get_by_index(linked_list_node *head, int index)
|
||||
void NATIVE64 linked_list_node_init(linked_list_node* node)
|
||||
{
|
||||
while(1)
|
||||
if(node != NULL)
|
||||
{
|
||||
if(index <= 0 || head == NULL)
|
||||
return head;
|
||||
head = head->next;
|
||||
index--;
|
||||
}
|
||||
}
|
||||
|
||||
linked_list_node* NATIVE64 _linked_list_get_by_element(linked_list_node *head, void *data, int(*compare)(int *, int *))
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(head == NULL || compare(data,head->data) == 0)
|
||||
return head;
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
linked_list_node* NATIVE64 _linked_list_create_node()
|
||||
{
|
||||
linked_list_node* node = (linked_list_node*)kmalloc(sizeof(linked_list_node));
|
||||
node->data = NULL;
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
void NATIVE64 _linked_list_delete_node(linked_list *list, linked_list_node *node)
|
||||
{
|
||||
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--;
|
||||
kfree(node);
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//interface
|
||||
linked_list* NATIVE64 linked_list_create()
|
||||
linked_list_node* NATIVE64 linked_list_node_get(linked_list_node * head, int index)
|
||||
{
|
||||
linked_list* list = (linked_list*)kmalloc(sizeof(linked_list));
|
||||
list->size = 0;
|
||||
list->tail = NULL;
|
||||
list->head = NULL;
|
||||
return list;
|
||||
if(head == NULL || index < 0)
|
||||
return NULL;
|
||||
while(index--)
|
||||
{
|
||||
head = head->next;
|
||||
if(head == NULL)
|
||||
break;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_free(linked_list* list, void(*delete_data)(void*))
|
||||
int NATIVE64 linked_list_node_size(linked_list_node* head)
|
||||
{
|
||||
if(list == NULL)
|
||||
return;
|
||||
linked_list_node* head = list->head;
|
||||
int i = 0;
|
||||
while(head != NULL)
|
||||
{
|
||||
linked_list_node* temp = head;
|
||||
i++;
|
||||
head = head->next;
|
||||
if(delete_data != NULL)
|
||||
delete_data(temp->data);
|
||||
kfree(temp);
|
||||
}
|
||||
kfree(list);
|
||||
return;
|
||||
return i;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_insert(linked_list * list, void* data)
|
||||
//returns new head
|
||||
linked_list_node* NATIVE64 linked_list_node_insert(linked_list_node * head, int index, linked_list_node* node)
|
||||
{
|
||||
if(list == NULL)
|
||||
return;
|
||||
linked_list_node* node = _linked_list_create_node();
|
||||
node->data = data;
|
||||
if(list->tail != NULL)
|
||||
if(head == NULL)
|
||||
return node;
|
||||
if(node == NULL || index < 0)
|
||||
return head;
|
||||
//@ head != NULL
|
||||
if(index == 0)
|
||||
{
|
||||
//already elements in the list
|
||||
//guaranteed that list->next == NULL
|
||||
node->prev = list->tail;
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
//insert at head
|
||||
node->prev = NULL;
|
||||
node->next = head;
|
||||
head->prev = node;
|
||||
return node;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no element case
|
||||
list->tail = node;
|
||||
list->head = node;
|
||||
linked_list_node* target = linked_list_node_get(head, index-1);
|
||||
if(target == NULL)
|
||||
return NULL;
|
||||
node->prev = target;
|
||||
node->next = target->next;
|
||||
if(target->next != NULL)
|
||||
target->next->prev = node;
|
||||
target->next = node;
|
||||
return head;
|
||||
}
|
||||
list->size++;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_node_add(linked_list_node * head, linked_list_node* node)
|
||||
{
|
||||
if(head == NULL || node == NULL)
|
||||
return;
|
||||
int size = linked_list_node_size(head);
|
||||
linked_list_node_insert(head,size,node);
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_insert_at(linked_list * list, int position, void* data)
|
||||
//returns new head
|
||||
linked_list_node* NATIVE64 linked_list_node_remove(linked_list_node *head, int index)
|
||||
{
|
||||
if(list != NULL && position >= 0 && position <= list->size)
|
||||
if(head == NULL || index < 0)
|
||||
return head;
|
||||
if(index == 0)
|
||||
{
|
||||
linked_list_node* next = head->next;
|
||||
head->next = NULL;
|
||||
head->prev = NULL;
|
||||
if(next != NULL)
|
||||
next->prev = NULL;
|
||||
return next;
|
||||
}
|
||||
else
|
||||
{
|
||||
linked_list_node *target = linked_list_node_get(head, index);
|
||||
if (target->prev != NULL)
|
||||
target->prev->next = target->next;
|
||||
if (target->next != NULL)
|
||||
target->next->prev = target->prev;
|
||||
target->prev = NULL;
|
||||
target->next = NULL;
|
||||
return head;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NATIVE64 linked_list_init(linked_list* list)
|
||||
{
|
||||
if(list != NULL)
|
||||
{
|
||||
list->size = 0;
|
||||
list->head = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_add(linked_list * list, linked_list_node* node)
|
||||
{
|
||||
if(list != NULL && node != NULL)
|
||||
{
|
||||
//@ node != NULL
|
||||
if (list->head == NULL)
|
||||
{
|
||||
linked_list_node* target = _linked_list_get_by_index(list->head, position);
|
||||
if(target == NULL)
|
||||
{
|
||||
//tail case
|
||||
linked_list_insert(list, data);
|
||||
list->head = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
//head or normal case
|
||||
linked_list_node* node = _linked_list_create_node();
|
||||
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++;
|
||||
}
|
||||
linked_list_node_add(list->head, node);
|
||||
list->size++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void* NATIVE64 linked_list_get(linked_list * list, int index)
|
||||
void NATIVE64 linked_list_insert(linked_list * list, int index, linked_list_node* node)
|
||||
{
|
||||
if(list == NULL || list->head == NULL || index < 0 || list->size <= index)
|
||||
if(list != NULL && index > 0 && node != NULL)
|
||||
{
|
||||
list->head = linked_list_node_insert(list->head, index, node);
|
||||
list->size++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
linked_list_node* NATIVE64 linked_list_get(linked_list * list, int index)
|
||||
{
|
||||
if(list == NULL || index < 0 || index >= list->size)
|
||||
return NULL;
|
||||
linked_list_node* node = _linked_list_get_by_index(list->head, index);
|
||||
return node == NULL ? NULL : node->data;
|
||||
return linked_list_node_get(list->head,index);
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_delete(linked_list * list, void* data, int(*compare)(int*,int*))
|
||||
void NATIVE64 linked_list_remove(linked_list *list, int index)
|
||||
{
|
||||
if(list == NULL || list->head == NULL || compare == NULL)
|
||||
return;
|
||||
linked_list_node* node = _linked_list_get_by_element(list->head, data, compare);
|
||||
_linked_list_delete_node(list, node);
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_delete_at(linked_list * list, int index)
|
||||
{
|
||||
if(list == NULL || list->head == NULL || index < 0 || list->size <= index)
|
||||
return;
|
||||
linked_list_node* node = _linked_list_get_by_index(list->head, index);
|
||||
_linked_list_delete_node(list, node);
|
||||
return;
|
||||
}
|
||||
|
||||
// iterator
|
||||
linked_list_iterator* NATIVE64 linked_list_create_iterator(linked_list* list)
|
||||
{
|
||||
if(list == NULL)
|
||||
return NULL;
|
||||
linked_list_iterator* it = (linked_list_iterator*)kmalloc(sizeof(linked_list_iterator));
|
||||
it->current = list->head;
|
||||
return it;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_delete_iterator(linked_list_iterator* it)
|
||||
{
|
||||
kfree(it);
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_prev(linked_list_iterator* it)
|
||||
{
|
||||
it->current = it->current->prev;
|
||||
return;
|
||||
}
|
||||
|
||||
void NATIVE64 linked_list_next(linked_list_iterator* it)
|
||||
{
|
||||
it->current = it->current->next;
|
||||
if(list != NULL && index >= 0 && index < list->size)
|
||||
{
|
||||
list->head = linked_list_node_remove(list->head, index);
|
||||
list->size--;
|
||||
}
|
||||
return;
|
||||
}
|
|
@ -1,44 +1,40 @@
|
|||
#ifndef _LINKED_LIST_H_
|
||||
#define _LINKED_LIST_H_
|
||||
#include "kdef.h"
|
||||
typedef struct _linked_list_node
|
||||
{
|
||||
struct _linked_list_node* prev;
|
||||
struct _linked_list_node* next;
|
||||
void* data;
|
||||
} linked_list_node;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
linked_list_node* head;
|
||||
linked_list_node* tail;
|
||||
int size;
|
||||
} linked_list;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
linked_list_node* current;
|
||||
} linked_list_iterator;
|
||||
void NATIVE64 linked_list_init(linked_list* list);
|
||||
|
||||
linked_list* NATIVE64 linked_list_create();
|
||||
void NATIVE64 linked_list_add(linked_list * list, linked_list_node* node);
|
||||
|
||||
void NATIVE64 linked_list_insert(linked_list * list, void* data);
|
||||
void NATIVE64 linked_list_insert(linked_list * list, int index, linked_list_node* node);
|
||||
|
||||
void NATIVE64 linked_list_insert_at(linked_list * list, int position, void* data);
|
||||
linked_list_node* NATIVE64 linked_list_get(linked_list * list, int index);
|
||||
|
||||
void* NATIVE64 linked_list_get(linked_list * list, int index);
|
||||
void NATIVE64 linked_list_remove(linked_list *list, int index);
|
||||
|
||||
void NATIVE64 linked_list_delete(linked_list * list, void* data, int(*compare)(int*,int*));
|
||||
|
||||
void NATIVE64 linked_list_delete_at(linked_list * list, int index);
|
||||
|
||||
linked_list_iterator* NATIVE64 linked_list_create_iterator(linked_list* list);
|
||||
int NATIVE64 linked_list_node_size(linked_list_node* head);
|
||||
|
||||
void NATIVE64 linked_list_delete_iterator(linked_list_iterator* it);
|
||||
void NATIVE64 linked_list_node_init(linked_list_node* node);
|
||||
|
||||
void NATIVE64 linked_list_prev(linked_list_iterator* it);
|
||||
void NATIVE64 linked_list_node_add(linked_list_node * head, linked_list_node* node);
|
||||
|
||||
void NATIVE64 linked_list_next(linked_list_iterator* it);
|
||||
linked_list_node* NATIVE64 linked_list_node_insert(linked_list_node * head, int index, linked_list_node* node);
|
||||
|
||||
void NATIVE64 linked_list_free(linked_list* list, void(*delete_data)(void*));
|
||||
linked_list_node* NATIVE64 linked_list_node_get(linked_list_node * head, int index);
|
||||
|
||||
linked_list_node* NATIVE64 linked_list_node_remove(linked_list_node *head, int index);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "type.h"
|
||||
#include "kdef.h"
|
||||
#include "linked_list.h"
|
||||
#define PML4_PRESENT (1ull << 0)
|
||||
#define PML4_WRITE (1ull << 1)
|
||||
#define PML4_USER (1ull << 2)
|
||||
|
@ -68,6 +69,13 @@ typedef struct __attribute__ ((packed))
|
|||
uint64_t base;
|
||||
} gdt_ptr_t;
|
||||
|
||||
typedef struct __attribute__ ((packed))
|
||||
{
|
||||
linked_list_node node;
|
||||
uint64_t base;
|
||||
uint64_t limit;
|
||||
} phy_mem_info;
|
||||
|
||||
void*NATIVE64 kmalloc(size_t const size);
|
||||
void NATIVE64 kfree(void* ptr);
|
||||
|
||||
|
|
Loading…
Reference in New Issue