]> git.mdlowis.com Git - archive/atc.git/commitdiff
Started implementation of splaytree for pointer lookups
authorMike D. Lowis <mike.lowis@gentex.com>
Tue, 7 Apr 2015 18:35:10 +0000 (14:35 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Tue, 7 Apr 2015 18:35:10 +0000 (14:35 -0400)
source/runtime/heap.c
source/runtime/splaytree.c
source/runtime/splaytree.h
tests/test_splaytree.c

index 66ab2cd4c5c4f7b9901a2c6cbf3bb69ac7e9c5ec..f4be807fea1a3f61c49d04a09ab25e6a4eda90a1 100644 (file)
@@ -90,41 +90,47 @@ void heap_finish_collection(heap_t* heap)
 }
 
 static void* subheap_find_and_mark(heap_t* heap, uintptr_t addr) {
-    void* obj = NULL;
-    for (uintptr_t i = 0; i < NUM_HEAP_STACKS; i++) {
-        for(segment_t* curr = heap->heaps[i].available; curr != NULL; curr = curr->next) {
-            obj = segment_find_and_mark(heap->heaps[i].available, addr);
-            if (NULL != obj) {
-                i = NUM_HEAP_STACKS;
-                break;
-            }
-        }
-    }
-    return obj;
+//    void* obj = NULL;
+//    for (uintptr_t i = 0; i < NUM_HEAP_STACKS; i++) {
+//        for(segment_t* curr = heap->heaps[i].available; curr != NULL; curr = curr->next) {
+//            obj = segment_find_and_mark(heap->heaps[i].available, addr);
+//            if (NULL != obj) {
+//                i = NUM_HEAP_STACKS;
+//                break;
+//            }
+//        }
+//    }
+//    return obj;
+    (void)heap;
+    (void)addr;
+    return NULL;
 }
 
 static void* block_find_and_mark(heap_t* heap, uintptr_t addr) {
-    void* obj = NULL;
-    block_t* prev = NULL;
-    block_t* curr = heap->greylist;
-    while (curr != NULL) {
-        uintptr_t start = (uintptr_t)&(curr->data[0]);
-        uintptr_t end   = start + curr->size;
-        if ((start <= addr) && (addr < end)) {
-            /* Remove it from the grey list */
-            if (prev == NULL)
-                heap->greylist = curr->next;
-            else
-                prev->next = curr->next;
-            /* Add it to the in-use list and break */
-            curr->next = heap->blocks;
-            heap->blocks = curr->next;
-            break;
-        }
-        prev = curr;
-        curr = curr->next;
-    }
-    return obj;
+//    void* obj = NULL;
+//    block_t* prev = NULL;
+//    block_t* curr = heap->greylist;
+//    while (curr != NULL) {
+//        uintptr_t start = (uintptr_t)&(curr->data[0]);
+//        uintptr_t end   = start + curr->size;
+//        if ((start <= addr) && (addr < end)) {
+//            /* Remove it from the grey list */
+//            if (prev == NULL)
+//                heap->greylist = curr->next;
+//            else
+//                prev->next = curr->next;
+//            /* Add it to the in-use list and break */
+//            curr->next = heap->blocks;
+//            heap->blocks = curr->next;
+//            break;
+//        }
+//        prev = curr;
+//        curr = curr->next;
+//    }
+//    return obj;
+    (void)heap;
+    (void)addr;
+    return NULL;
 }
 
 void* heap_find_and_mark(heap_t* heap, uintptr_t addr)
index 37d9c5df2564ef8f1c37dbeec07176b7d1c19f89..c041843b9d3888c6b10df44dd1c6afffb4dd1a0d 100644 (file)
@@ -5,13 +5,11 @@
 #include "splaytree.h"
 #include <stdlib.h>
 
-static node_t* create_tree(uintptr_t val) {
-    node_t* node = (node_t*)malloc(sizeof(node_t));
-    node->value  = val;
-    node->parent = NULL;
-    node->left   = NULL;
-    node->right  = NULL;
-    return node;
+splaytree_t* splaytree_create(void)
+{
+    splaytree_t* splaytree = (splaytree_t*)malloc(sizeof(splaytree_t));
+    splaytree->root = NULL;
+    return splaytree;
 }
 
 static void destroy_tree(node_t* node) {
@@ -21,52 +19,85 @@ static void destroy_tree(node_t* node) {
     }
 }
 
-splaytree_t* splaytree_create(comp_fn_t cfn)
-{
-    splaytree_t* splaytree = (splaytree_t*)malloc(sizeof(splaytree_t));
-    splaytree->compare = cfn;
-    splaytree->root    = NULL;
-    return splaytree;
-}
-
 void splaytree_destroy(splaytree_t* tree)
 {
     destroy_tree(tree->root);
     free(tree);
 }
 
-void splaytree_insert(splaytree_t* tree, uintptr_t value)
+static node_t* create_node(node_type_t tag, void* value) {
+    node_t* node = (node_t*)malloc(sizeof(node_t*));
+    node->tag = tag;
+    node->ptr.raw = value;
+    node->left = NULL;
+    node->right = NULL;
+    return node;
+}
+
+static uintptr_t get_start_addr(node_t* curr) {
+    if (curr->tag == SEGMENT)
+        return (uintptr_t)(curr->ptr.segment->start);
+    else
+        return (uintptr_t)(curr->ptr.block->data);
+}
+
+static uintptr_t get_end_addr(node_t* curr) {
+    if (curr->tag == SEGMENT)
+        return (uintptr_t)(curr->ptr.segment->end);
+    else
+        return (uintptr_t)(curr->ptr.block->data + curr->ptr.block->size);
+}
+
+static node_t** next_node(node_t* curr, uintptr_t address) {
+    uintptr_t curr_address = get_start_addr(curr);
+    if (address < curr_address)
+        return &(curr->left);
+    else
+        return &(curr->right);
+}
+
+void splaytree_insert(splaytree_t* tree, node_type_t tag, void* value)
 {
-    if (tree->root == NULL) {
-        tree->root = create_tree(value);
-    } else {
-        node_t* curr = tree->root;
-        while (1) {
-            int cmp = tree->compare(value, curr->value);
-            if (0 == cmp) {
-                break;
-            } else if (cmp < 1) {
-                if (NULL == curr->left) {
-                    curr->left = create_tree(value);
-                } else {
-                    curr = curr->left;
-                }
-            } else if (cmp > 1) {
-                if (NULL == curr->right) {
-                    curr->right = create_tree(value);
-                } else {
-                    curr = curr->right;
-                }
-            }
+    /* Get the address of the start of the range */
+    uintptr_t address;
+    if (SEGMENT == tag)
+        address = (uintptr_t)((segment_t*)value)->start;
+    else
+        address = (uintptr_t)((block_t*)value)->data;
+    /* Insert the item into the tree */
+    if (tree->root == NULL)
+        tree->root = create_node(tag, value);
+    else {
+        node_t** current = &(tree->root);
+        while(*current != NULL) {
+            current = next_node(*current, address);
         }
+        *current = create_node(tag, value);
     }
 }
 
-uintptr_t splaytree_lookup(splaytree_t* tree, uintptr_t value)
+node_type_t splaytree_lookup(splaytree_t* tree, uintptr_t address, void** value)
 {
-    (void)tree;
-    (void)value;
-    return 0;
+    node_type_t tag = NONE;
+    node_t** current = &(tree->root);
+    while(*current != NULL) {
+        uintptr_t start = get_start_addr(*current);
+        uintptr_t end   = get_end_addr(*current);
+        if ((start <= address) && (address < end)) {
+            *value = (*current)->ptr.raw;
+            break;
+        } else if (start < address) {
+            current = &((*current)->left);
+        } else {
+            current = &((*current)->right);
+        }
+    }
+    return tag;
 }
 
+void splaytree_delete(splaytree_t* tree, uintptr_t address)
+{
+    (void)tree;
+    (void)address;
+}
 
index 2689ab0d10df4a0a2b04a2a178d1b9f18311bd73..71dc69083314fea9959ea118d81fbbefd91482a8 100644 (file)
@@ -6,27 +6,33 @@
 #define SPLAYTREE_H
 
 #include <stdint.h>
+#include "heap.h"
+
+typedef enum { SEGMENT, BLOCK, NONE } node_type_t;
 
 typedef struct node_t {
-    uintptr_t value;
-    struct node_t* parent;
+    node_type_t tag;
+    union {
+        segment_t* segment;
+        block_t* block;
+        void* raw;
+    } ptr;
     struct node_t* left;
     struct node_t* right;
 } node_t;
 
-typedef int (*comp_fn_t)(uintptr_t key, uintptr_t cval);
-
 typedef struct splaytree_t {
-    comp_fn_t compare;
     node_t*   root;
 } splaytree_t;
 
-splaytree_t* splaytree_create(comp_fn_t cfn);
+splaytree_t* splaytree_create(void);
 
 void splaytree_destroy(splaytree_t* tree);
 
-void splaytree_insert(splaytree_t* tree, uintptr_t value);
+void splaytree_insert(splaytree_t* tree, node_type_t tag, void* value);
+
+node_type_t splaytree_lookup(splaytree_t* tree, uintptr_t address, void** value);
 
-uintptr_t splaytree_lookup(splaytree_t* tree, uintptr_t value);
+void splaytree_delete(splaytree_t* tree, uintptr_t address);
 
 #endif /* SPLAYTREE_H */
index 157e070f1575c18febc0fb36605d24784183192c..e4a783ce8dfd138d2671daaad6423e335b5c0fe5 100644 (file)
@@ -5,8 +5,7 @@ TEST_SUITE(SplayTree) {
     /* Verify: splaytree_create
      *************************************************************************/
     TEST(Verify_Create_allocates_and_initializes_an_empty_tree) {
-        splaytree_t* tree = splaytree_create((comp_fn_t)0x1234);
-        CHECK(tree->compare == (comp_fn_t)0x1234);
+        splaytree_t* tree = splaytree_create();
         CHECK(tree->root    == NULL);
         splaytree_destroy(tree);
     }