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:
HyperAssembler 2015-03-21 14:17:38 -07:00
parent ab103126b6
commit 7db4e9cf35
10 changed files with 524 additions and 459 deletions

84
Test/avl_tree_test.c Normal file
View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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
{

View File

@ -1 +0,0 @@
#include "int.h"

View File

@ -1,3 +0,0 @@
#ifndef _INT_H_
#define _INT_H_
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -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);