view src/insert_verification/allocate.c @ 24:8ca38f736745

Fill allocated memory spaces by zero
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Wed, 13 Apr 2016 16:19:05 +0900
parents dcfd4b848886
children
line wrap: on
line source

#include <stdio.h>
#include <string.h>

#include "llrbContext.h"

void* akashaMalloc(struct Context* context, size_t size) {
    context->data[++context->dataNum] = context->heap;
    context->heap += size;
    return context->data[context->dataNum];
}


struct Node* nodeDeepCopy(struct Context* newContext, struct Node* oldNode) {
    if (oldNode == NULL) return NULL;

    struct Node* newNode = akashaMalloc(newContext, sizeof(struct Node));
    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;
}

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

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 = akashaMalloc(newContext, sizeof(struct Tree));
    treeDeepCopy(newContext, newIter->tree, 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) {
    struct Context* newContext = (struct Context*)malloc(sizeof(struct Context));

    newContext->heapLimit = oldContext->heapLimit*2;
    newContext->code      = oldContext->code;
    newContext->data      = malloc((newContext->heapLimit / sizeof(union Data)) * 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[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);
    iterDeepCopy(newContext, &newContext->data[Iter]->iterator, &oldContext->data[Iter]->iterator);

    newContext->node_stack = oldContext->node_stack;
    newContext->code_stack = oldContext->code_stack;
    newContext->next       = oldContext->next;
    free(oldContext->data);
    *oldContext = *newContext;
}

void allocator(struct Context* context) {
    struct Allocate* allocate = &context->data[Allocate]->allocate;

    if ((((long)context->heap - (long)context->heapStart) > (context->heapLimit - allocate->size)) ||
          (context->dataNum >= (context->heapLimit / sizeof(union Data)))) {
        memoryRefresh(context);
    }
    context->data[++context->dataNum] = context->heap;
    context->heap += allocate->size;
    allocate->size = 0;
}