changeset 13:f0a1f02e8493

Enumerate single path using iterator
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Sun, 20 Mar 2016 18:23:58 +0900
parents 78dce131e9d6
children 1bbaafdafa47
files src/insert_verification/akashaLLRBContext.c src/insert_verification/include/akashaLLRBContext.h src/insert_verification/main.c
diffstat 3 files changed, 107 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/insert_verification/akashaLLRBContext.c	Fri Mar 18 10:57:40 2016 +0900
+++ b/src/insert_verification/akashaLLRBContext.c	Sun Mar 20 18:23:58 2016 +0900
@@ -2,9 +2,10 @@
 
 #include "akashaLLRBContext.h"
 
-extern __code insertOnce_stub(struct Context*);
 extern __code showTree_stub(struct Context*);
 extern __code iterateInsertion_stub(struct Context*);
+extern __code putAndGoToNextDepth_stub (struct Context*);
+extern __code duplicateIterator_stub(struct Context*);
 
 /* definitions from llrb */
 extern __code meta(struct Context*, enum Code next);
@@ -58,9 +59,10 @@
 
     context->codeNum = Exit;
 
-    context->code[InsertOnce]       = insertOnce_stub;
-    context->code[ShowTree]         = showTree_stub;
-    context->code[IterateInsertion] = iterateInsertion_stub;
+    context->code[ShowTree]            = showTree_stub;
+    context->code[IterateInsertion]    = iterateInsertion_stub;
+    context->code[PutAndGoToNextDepth] = putAndGoToNextDepth_stub;
+    context->code[DuplicateIterator]   = duplicateIterator_stub;
 
     /* definitions from llrb */
     context->code[Put]           = put_stub;
@@ -127,7 +129,7 @@
 }
 
 __code initIteratorElem(struct Context* context, struct Allocate* allocate, struct IterElem* prev) {
-    if (prev->val >= LIMIT_OF_VERIFICATION_SIZE) { goto initFinishIterator(context, prev); }
+    if (prev->val+1 == LIMIT_OF_VERIFICATION_SIZE) { goto initFinishIterator(context, prev); }
 
     struct IterElem* ie = context->heap;
     allocate->size = sizeof(struct IterElem);
--- a/src/insert_verification/include/akashaLLRBContext.h	Fri Mar 18 10:57:40 2016 +0900
+++ b/src/insert_verification/include/akashaLLRBContext.h	Sun Mar 20 18:23:58 2016 +0900
@@ -2,12 +2,13 @@
 #include "stack.h"
 
 #define ALLOCATE_SIZE 1000
-#define LIMIT_OF_VERIFICATION_SIZE 16
+#define LIMIT_OF_VERIFICATION_SIZE 2
 
 enum Code {
-    InsertOnce,
     ShowTree,
     IterateInsertion,
+    PutAndGoToNextDepth,
+    DuplicateIterator,
 
     /* definitions from llrb */
     Allocator,
--- a/src/insert_verification/main.c	Fri Mar 18 10:57:40 2016 +0900
+++ b/src/insert_verification/main.c	Sun Mar 20 18:23:58 2016 +0900
@@ -3,6 +3,8 @@
 #include "akashaLLRBContext.h"
 #include "akashaCS.h"
 
+extern void allocator(struct Context* context);
+
 void printTree(struct Node* node, int n) {
     if (node != 0) {
         printTree(node->left, n+1);
@@ -13,18 +15,6 @@
     }
 }
 
-__code insertOnce_stub(struct Context* context) {
-    goto insertOnce(context, &context->data[Node]->node);
-}
-
-__code insertOnce(struct Context* context, struct Node* node) {
-    node->key   = rand()%100+1;
-    node->value = 100;
-
-    context->next = ShowTree;
-    goto meta(context, Put);
-}
-
 __code showTree_stub(struct Context* context) {
     goto showTree(context, &context->data[Tree]->tree);
 }
@@ -44,17 +34,107 @@
 }
 
 __code iterateInsertion(struct Context* context, struct Iterator* iter, struct Node* node) {
+    // puts all elements in iterator into tree.
+    node->key   = iter->head->val;
+    node->value = iter->head->val;
+    iter->head  = iter->head->next;
+
+    if (iter->head == iter->last) {
+        context->next = ShowTree;
+    } else {
+        context->next = IterateInsertion;
+    }
+    goto meta(context, Put);
+}
+
+__code putAndGoToNextDepth_stub(struct Context* context) {
+    goto putAndGoToNextDepth(context, &context->data[Iter]->iterator, &context->data[Tree]->tree, &context->data[Node]->node);
+}
+
+__code putAndGoToNextDepth(struct Context* context, struct Iterator* iter, struct Tree* tree, struct Node* node) {
     node->key   = iter->head->val;
     node->value = iter->head->val;
     iter->head  = iter->head->next;
-    if (iter->head == iter->last) { goto meta(context, ShowTree); }
 
-    //printf("Trying insertion %d", node->key);
-
-    context->next = IterateInsertion;
+    if (iter->head == iter->last) {
+        context->next = ShowTree; // TODO: add restore and  back trace
+    } else {
+        context->next = DuplicateIterator;
+    }
     goto meta(context, Put);
 }
 
+__code duplicateIterator_stub(struct Context* context) {
+    goto duplicateIterator(context, &context->data[Allocate]->allocate, &context->data[Iter]->iterator);
+}
+
+__code duplicateIterator(struct Context* context, struct Allocate* allocate, struct Iterator* iter) {
+    struct Iterator* newIter = context->heap;
+    allocate->size = sizeof(struct Iterator);
+    allocator(context);
+
+    struct IterElem* dup = context->heap;
+    allocate->size = sizeof(struct IterElem);
+    allocator(context);
+
+    dup->val  = iter->head->val;
+    dup->next = NULL;
+
+    newIter->previousDepth = iter;
+    newIter->head          = dup;
+    newIter->last          = NULL;
+    context->data[Iter]    = (union Data*) newIter;
+
+    goto duplicateIteratorElem_stub(context);
+}
+
+__code duplicateIteratorElem_stub(struct Context* context) {
+    goto duplicateIteratorElem(context, &context->data[Allocate]->allocate, &context->data[Iter]->iterator);
+}
+
+__code duplicateIteratorElem(struct Context* context, struct Allocate* allocate, struct Iterator* iter) {
+    // All elements in iterator must be unique.
+
+    if ((iter->last != NULL) && (iter->last == iter->previousDepth->last)) {
+        goto meta(context, ShowTree); /* copy tree */
+    }
+    struct IterElem* dup = context->heap;
+    allocate->size = sizeof(struct IterElem);
+    allocator(context);
+
+    struct IterElem *oldElem = iter->previousDepth->head;
+    struct IterElem *newElem = iter->head;
+
+
+    while ((newElem->next != NULL) && (oldElem->val == newElem->val)) {
+        // FIXME: simple implementation O(n^2)
+        oldElem = oldElem->next;
+        newElem = newElem->next;
+    }
+
+    dup->val         = oldElem->next->val;
+    newElem->next    = dup;
+
+    if (oldElem->next == iter->previousDepth->last) {
+        dup->next  = iter->head;
+        iter->last = dup;
+        goto duplicateTree_stub(context); // meta
+    }
+
+    goto duplicateIteratorElem_stub(context); // meta
+}
+
+__code duplicateTree_stub(struct Context* context) {
+    goto duplicateTree(context, &context->data[Tree]->tree, &context->data[Iter]->iterator);
+}
+
+__code duplicateTree(struct Context* context, struct Tree* tree, struct Iterator* iter) {
+    // Tree must be non destructive.
+    // If you use destructive tree, you must copy tree.
+    iter->tree = tree;
+    goto meta(context, PutAndGoToNextDepth);
+}
+
 int main(int argc, char const* argv[]) {
-    goto startCode(IterateInsertion);
+    goto startCode(PutAndGoToNextDepth);
 }