Mercurial > hg > CbC > old > akasha
changeset 26:cf7cbe70404f
WIP: Trying implement copying GC...
author | Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 16 Apr 2016 09:44:48 +0900 |
parents | 38ba1606e62d |
children | a416dd4093cf |
files | src/insert_verification/akashaCS.c src/insert_verification/include/akashaLLRBContext.h src/insert_verification/main.c |
diffstat | 3 files changed, 125 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/src/insert_verification/akashaCS.c Wed Apr 13 16:30:47 2016 +0900 +++ b/src/insert_verification/akashaCS.c Sat Apr 16 09:44:48 2016 +0900 @@ -1,21 +1,71 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include "akashaLLRBContext.h" extern __code initLLRBContext(struct Context*, enum Code); -void* akashaMalloc(struct Context* context, size_t size) { - context->data[++context->dataNum] = context->heap; - context->heap += size; - return context->data[context->dataNum]; +/* utils */ + +void* akashaMalloc(struct Context* akashaContext, unsigned int size) { + akashaContext->data[++akashaContext->dataNum] = akashaContext->heap; + akashaContext->heap += size; + return akashaContext->data[akashaContext->dataNum]; +} + +bool eqNode(struct Node* n1, struct Node* n2) { + if ((n1 == NULL) && (n2 == NULL)) return true; + if (n1->key != n2->key) return false; + if (n1->value != n2->value) return false; + if (n1->color != n2->color) return false; + if (!eqNode(n1->left, n2->left)) return false; + if (!eqNode(n1->right, n2->right)) return false; + return true; } +bool eqTree(struct Tree* t1, struct Tree* t2) { + if ((t1 == NULL) && (t2 == NULL)) return true; + if (t1->next != t2->next) return false; + if (t2->result != t2->result) return false; + if (!eqNode(t1->root, t2->root)) return false; + if (!eqNode(t1->current, t2->current)) return false; + if (!eqNode(t1->deleted, t2->deleted)) return false; + return true; +} + + +bool eqIter(struct Iterator* iter1, struct Iterator* iter2) { + if (iter1->head->val != iter2->head->val) return false; + if (iter1->last->val != iter2->last->val) return false; + if (iter1->iteratedValue != iter2->iteratedValue) return false; + if (!eqTree(iter1->tree, iter2->tree)) return false; + + struct IterElem *ie1 = iter1->head->next; + struct IterElem *ie2 = iter2->head->next; + + while (ie1->val != iter1->head->val) { + if (ie1->val != ie2->val) return false; + ie1 = ie1->next; + ie2 = ie2->next; + } + + if ((iter1->previousDepth == NULL) && (iter2->previousDepth == NULL)) return true; + return eqIter(iter1->previousDepth, iter2->previousDepth); +} + + +/* C function */ + struct Node* nodeDeepCopy(struct Context* newContext, struct Node* oldNode) { if (oldNode == NULL) return NULL; - struct Node* newNode = akashaMalloc(newContext, sizeof(struct Node)); + struct Allocate* allocate = &newContext->data[Allocate]->allocate; + allocate->size = sizeof(Node); + allocator(newContext); + + struct Node* newNode = (struct Node*)newContext->data[newContext->dataNum]; newNode->next = oldNode->next; newNode->key = oldNode->key; newNode->value = oldNode->value; @@ -36,13 +86,21 @@ return newNode; } -void treeDeepCopy(struct Context* newContext, struct Tree* newTree, struct Tree* oldTree) { - if (oldTree == NULL) return; - newTree->next = oldTree->next; - newTree->result = oldTree->result; - newTree->root = nodeDeepCopy(newContext, oldTree->root); - newTree->current = nodeDeepCopy(newContext, oldTree->current); - newTree->deleted = nodeDeepCopy(newContext, oldTree->deleted); +struct Tree* treeDeepCopy(struct Context* newContext, struct Tree* oldTree) { + if (oldTree == NULL) return NULL; + + struct Allocate* allocate = &newContext->data[Allocate]->allocate; + allocate->size = sizeof(Node); + allocator(newContext); + + struct Tree* newTree = (struct Tree*)newContext->data[newContext->dataNum]; + newTree->next = oldTree->next; + newTree->result = oldTree->result; + newTree->root = nodeDeepCopy(newContext, oldTree->root); + newTree->current = nodeDeepCopy(newContext, oldTree->current); + newTree->deleted = nodeDeepCopy(newContext, oldTree->deleted); + + return newTree; } void iterElemDeepCopy(struct Context* newContext, struct Iterator* newIter, struct Iterator *oldIter) { @@ -68,11 +126,9 @@ } void iterDeepCopy(struct Context* newContext, struct Iterator* newIter, struct Iterator* oldIter) { - newIter->tree = akashaMalloc(newContext, sizeof(struct Tree)); - treeDeepCopy(newContext, newIter->tree, oldIter->tree); + newIter->tree = treeDeepCopy(newContext, oldIter->tree); newIter->iteratedValue = oldIter->iteratedValue; - iterElemDeepCopy(newContext, newIter, oldIter); if (oldIter->previousDepth != NULL) { @@ -89,8 +145,8 @@ struct Context* newContext = (struct Context*)malloc(sizeof(struct Context)); - newContext->dataLimit = oldContext->dataLimit*2; - newContext->heapLimit = oldContext->heapLimit*2; + newContext->dataLimit = oldContext->dataLimit; + newContext->heapLimit = oldContext->heapLimit; newContext->code = oldContext->code; newContext->data = malloc(newContext->dataLimit * sizeof(union Data*)); newContext->heapStart = malloc(newContext->heapLimit); @@ -109,27 +165,54 @@ newContext->data[Node] = newContext->heap; newContext->heap += sizeof(struct Node); - newContext->data[Node]->node = oldContext->data[Node]->node; newContext->data[Iter] = newContext->heap; newContext->heap += sizeof(struct Iterator); newContext->dataNum = Iter; - treeDeepCopy(newContext, &newContext->data[Tree]->tree, &oldContext->data[Tree]->tree); + newContext->data[Node]->node = *nodeDeepCopy(newContext, &oldContext->data[Node]->node); + newContext->data[Tree]->tree = *treeDeepCopy(newContext, &oldContext->data[Tree]->tree); + if (!eqTree(&newContext->data[Tree]->tree, &oldContext->data[Tree]->tree)) abort(); iterDeepCopy(newContext, &newContext->data[Iter]->iterator, &oldContext->data[Iter]->iterator); + if (!eqIter(&newContext->data[Iter]->iterator, &oldContext->data[Iter]->iterator)) abort(); newContext->node_stack = oldContext->node_stack; newContext->code_stack = oldContext->code_stack; newContext->next = oldContext->next; free(oldContext->data); + free(oldContext->heapStart); *oldContext = *newContext; } +void validateNodePointer(struct Node* node) { + if (node == NULL) return; + validateNodePointer(node->left); + validateNodePointer(node->right); +} + +void validateTreePointer(struct Tree* tree) { + if (tree == NULL) return; + validateNodePointer(tree->root); + validateNodePointer(tree->current); + validateNodePointer(tree->deleted); +} + + +void findInvalidPointer(struct Context* context) { + validateNodePointer(&context->data[Node]->node); + validateTreePointer(&context->data[Tree]->tree); +} + +/* Code Segments */ + __code meta(struct Context* context, enum Code next) { - if ((next == Put) && (context->dataNum > (context->dataLimit * 0.9))) { - memoryRefresh(context); + if (next == Put) { + findInvalidPointer(context); + if (context->dataNum > (context->dataLimit * 0.9)) memoryRefresh(context); } + findInvalidPointer(context); + context->prev = next; goto (context->code[next])(context); }
--- a/src/insert_verification/include/akashaLLRBContext.h Wed Apr 13 16:30:47 2016 +0900 +++ b/src/insert_verification/include/akashaLLRBContext.h Sat Apr 16 09:44:48 2016 +0900 @@ -1,8 +1,8 @@ /* Context definition for llrb example */ #include "stack.h" -#define ALLOCATE_SIZE 100000 -#define LIMIT_OF_VERIFICATION_SIZE 11 +#define ALLOCATE_SIZE 20000000 +#define LIMIT_OF_VERIFICATION_SIZE 8 enum Code { ShowTree, @@ -65,6 +65,7 @@ struct Context { enum Code next; + enum Code prev; unsigned int codeNum; __code (**code) (struct Context*); void* heapStart;
--- a/src/insert_verification/main.c Wed Apr 13 16:30:47 2016 +0900 +++ b/src/insert_verification/main.c Sat Apr 16 09:44:48 2016 +0900 @@ -1,8 +1,11 @@ +#include <stdbool.h> #include <stdio.h> #include "akashaLLRBContext.h" #include "akashaCS.h" +extern struct Tree* treeDeepCopy(struct Context* newContext, struct Tree* oldTree); // FIXME +extern bool eqTree(struct Tree*, struct Tree*); extern void allocator(struct Context* context); void showTrace(struct Iterator* iter); //FIXME @@ -159,35 +162,32 @@ struct IterElem *oldElem = iter->previousDepth->head->next; struct IterElem *newElem = iter->head; - while (newElem->next != NULL) { - // FIXME: simple implementation O(n^2) - oldElem = oldElem->next; - newElem = newElem->next; - } - - if (oldElem->val == iter->previousDepth->iteratedValue) { - newElem->next = iter->head; - iter->last = iter->head; - goto meta(context, DuplicateTree); - } else { - struct IterElem* dup = context->heap; + while (oldElem->val != iter->previousDepth->iteratedValue) { allocate->size = sizeof(struct IterElem); allocator(context); - dup->val = oldElem->val; - newElem->next = dup; - goto meta(context, DuplicateIteratorElem); + newElem->next = (struct IterElem*)context->data[context->dataNum]; + newElem->next->val = oldElem->val; + + newElem = newElem->next; + oldElem = oldElem->next; } + newElem->next = iter->head; + iter->last = iter->head; + goto meta(context, DuplicateTree); } __code duplicateTree_stub(struct Context* context) { - goto duplicateTree(context, &context->data[Tree]->tree, &context->data[Iter]->iterator); + goto duplicateTree(context, &context->data[Allocate]->allocate, &context->data[Tree]->tree, &context->data[Iter]->iterator); } -__code duplicateTree(struct Context* context, struct Tree* tree, struct Iterator* iter) { +__code duplicateTree(struct Context* context, struct Allocate* allocate, struct Tree* tree, struct Iterator* iter) { // Tree must be non destructive. // If you use destructive tree, you must copy tree. - iter->previousDepth->tree = tree; + allocate->size = sizeof(Tree); + allocator(context); + iter->previousDepth->tree = treeDeepCopy(context, tree); + if (!eqTree(iter->previousDepth->tree, tree)) abort(); goto meta(context, PutAndGoToNextDepth); }