view src/llrb/llrb.c @ 20:324c44f2076f

implement insert
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Tue, 28 Apr 2015 04:31:19 +0900
parents 9302b1a48008
children 737a900518be
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>

#include "llrbContext.h"

#include "allocate.h"
#include "origin_cs.h"

#ifdef CLANG
#define _CbC_retrun __return
#define _CbC_environment __environment
#endif

#define NUM 100
#define ALLOCATE_SIZE 1024

extern __code initLLRBContext(struct Context* context);
void colorFlip(struct Context*);
void rotateLeft(struct Context*);
void rotateRight(struct Context*);
/* 
__code code1(Allocate allocate) {
    allocate.size = sizeof(long);
    allocate.next = Code2;
    goto Allocate(allocate);
}
*/

__code code1(struct Context* context) {
    context->data[0]->allocate.size = sizeof(struct Node);
    context->data[0]->allocate.next = Put;
    context->data[0]->allocate.after_put = Code2;
    context->data[0]->allocate.key = 0;
    context->data[0]->allocate.value = 0;
    goto meta(context, Allocate);
}

__code meta(struct Context* context, enum Code next) {
    goto (context->code[next])(context);
}

__code put(struct Context* context) {
    context->data[context->dataSize]->node.key = context->data[0]->allocate.key;
    context->data[context->dataSize]->node.value = context->data[0]->allocate.value;
    if (context->root == 0) {
        context->root = context->data[context->dataSize];
        context->root->node.color = Black;
        goto meta(context, context->data[0]->allocate.after_put);
    }
    context->data[context->dataSize]->node.color = Red;
    context->current = context->root;
    goto meta(context, Insert);
}

__code insert(struct Context* context) {
    int persistentKey = context->current->node.key;
    int temporalKey = context->data[context->dataSize]->node.key;
    
    if (context->current->node.right != 0 && context->current->node.left != 0) {
        if (context->current->node.right->node.color == Red && context->current->node.left->node.color == Red) {
            colorFlip(context);
        }
    }
    
    if (persistentKey == temporalKey) {
        context->current->node.value = context->data[context->dataSize]->node.value;
        goto meta(context, context->data[0]->allocate.after_put);
    } else if (persistentKey < temporalKey) {
        if (context->current->node.left == 0) {
            context->current->node.left = context->data[context->dataSize];
        } else {
            context->current = context->current->node.left;
            goto meta(context, Insert);
        }
    } else {
        if (context->current->node.right == 0) {
            context->current->node.right = context->data[context->dataSize];
        } else {
            context->current = context->current->node.right;
            goto meta(context, Insert);
        }
    }

    if (context->current->node.right != 0) {
        if (context->current->node.right->node.color == Red) {
            rotateLeft(context);
        }
    }

    if (context->current->node.left != 0) {
        if (context->current->node.left->node.left != 0) {
            if (context->current->node.left->node.color == Red && context->current->node.left->node.left->node.color == Red) {
                rotateRight(context);
            }
        }
    }

    if (context->current->node.right != 0 && context->current->node.left != 0) {
        if (context->current->node.right->node.color == Red && context->current->node.left->node.color == Red) {
            colorFlip(context);
        }
    }    
    
    context->root->node.color = Black;
    
    goto meta(context, context->data[0]->allocate.after_put);
}

void rotateLeft(struct Context* context) {
    union Data* tmp = context->current->node.right;
    context->current->node.right = tmp->node.left;
    tmp->node.left = context->current;
    tmp->node.color = tmp->node.left->node.color;
    tmp->node.left->node.color = Red;
    context->current = tmp;
}

void rotateRight(struct Context* context) {
    union Data* tmp = context->current->node.left;
    context->current->node.left = tmp->node.right;
    tmp->node.right = context->current;
    tmp->node.color = tmp->node.right->node.color;
    tmp->node.right->node.color = Red;
    context->current = tmp;
}

void colorFlip(struct Context* context) {
    context->current->node.color ^= 1;
    context->current->node.left->node.color ^= 1;
    context->current->node.right->node.color ^= 1;
}

/*
__code code2(Allocate allocate, Count count) {
    count.count = 0;
    goto code3(count);
}
*/

__code code2(struct Context* context) {
    goto meta(context, Exit);
}

int main() {
    struct Context* context = (struct Context*)malloc(sizeof(struct Context));
    context->code = malloc(sizeof(__code*)*ALLOCATE_SIZE);
    context->data = malloc(sizeof(union Data**)*ALLOCATE_SIZE);
    context->heap = malloc(sizeof(union Data*)*ALLOCATE_SIZE);
    initLLRBContext(context);
    goto start_code(context, Code1);
}