Mercurial > hg > CbC > old > akasha
view src/insert_verification/akashaCS.c @ 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 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include "akashaLLRBContext.h" extern __code initLLRBContext(struct Context*, enum Code); /* 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 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; newNode->color = oldNode->color; if (oldNode->left != NULL) { newNode->left = nodeDeepCopy(newContext, oldNode->left); } else { newNode->left = NULL; } if (oldNode->right != NULL) { newNode->right = nodeDeepCopy(newContext, oldNode->right); } else { newNode->right = NULL; } return newNode; } 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) { newIter->head = (struct IterElem*)akashaMalloc(newContext, sizeof(struct IterElem)); newIter->head->val = oldIter->head->val; struct IterElem *oldElem = oldIter->head; struct IterElem *newElem = newIter->head; while (1) { if (oldElem->next->val == oldIter->head->val) break; newElem->next = akashaMalloc(newContext, sizeof(struct IterElem)); newElem->next->val = oldElem->next->val; newElem = newElem->next; oldElem = oldElem->next; } newElem->next = newIter->head; while (newElem->val != oldIter->last->val) { newElem = newElem->next; } newIter->last = newElem; } void iterDeepCopy(struct Context* newContext, struct Iterator* newIter, struct Iterator* oldIter) { newIter->tree = treeDeepCopy(newContext, oldIter->tree); newIter->iteratedValue = oldIter->iteratedValue; iterElemDeepCopy(newContext, newIter, oldIter); if (oldIter->previousDepth != NULL) { newIter->previousDepth = akashaMalloc(newContext, sizeof(struct Iterator)); iterDeepCopy(newContext, newIter->previousDepth, oldIter->previousDepth); } else { newIter->previousDepth = NULL; } } void memoryRefresh(struct Context* oldContext) { if (oldContext->node_stack->num != 0) { abort(); } if (oldContext->code_stack->num != 0) { abort(); } struct Context* newContext = (struct Context*)malloc(sizeof(struct Context)); 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); newContext->codeNum = Exit; newContext->heap = newContext->heapStart; memset(newContext->heapStart, newContext->heapLimit, 0); printf("reallocation! : %lu\n", newContext->heapLimit); newContext->data[Allocate] = newContext->heap; newContext->heap += sizeof(struct Allocate); newContext->data[Allocate]->allocate = oldContext->data[Allocate]->allocate; newContext->data[Tree] = newContext->heap; newContext->heap += sizeof(struct Tree); newContext->data[Node] = newContext->heap; newContext->heap += sizeof(struct Node); newContext->data[Iter] = newContext->heap; newContext->heap += sizeof(struct Iterator); newContext->dataNum = Iter; 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) { findInvalidPointer(context); if (context->dataNum > (context->dataLimit * 0.9)) memoryRefresh(context); } findInvalidPointer(context); context->prev = next; goto (context->code[next])(context); } __code startCode(enum Code next) { struct Context* context = (struct Context*)malloc(sizeof(struct Context)); goto initLLRBContext(context, next); } __code exitCode(struct Context* context) { free(context->code); free(context->data); free(context->heapStart); goto exit(0); }