From b97bf3ca4c5f7c86384622c0b6c0c45bae147416 Mon Sep 17 00:00:00 2001 From: "Valeriano A.R" Date: Wed, 3 Dec 2014 02:21:53 +0100 Subject: [PATCH] AccionFileNode_CompareChilds: Change algorithm complexity from O(n3) to O(n2) --- src/filenodecmp.c | 128 ++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/src/filenodecmp.c b/src/filenodecmp.c index 9149ae0..2b994c2 100644 --- a/src/filenodecmp.c +++ b/src/filenodecmp.c @@ -58,83 +58,91 @@ AccionFileNode *AccionFileNode_CreateNormal(FileNode *fileNodeLeft, return actionFileNode; } + void AccionFileNode_CompareChilds(AccionFileNode *actionFileNodeRoot, AccionFileNode **actionFileNodeQueue, void (*CheckPair)(FileNode *fileNodeLeft, FileNode *fileNodeRight, AccionFileNode **actionFileNodeQueue)) { - FileNode *fileNodeLeft, *fileNodeRight; - AccionFileNode *actionFileNodeQueueStart = (*actionFileNodeQueue); + FileNode *fileNodeLeft; + FileNode *fileNodeRight; + FileNode *fileNodeRightQueue; + FileNode *fileNodeRightProcessed; + FileNode *fileNodeRightPrevious; - // Comprobar si hay algo que comparar + // Check if there is something to do if (!actionFileNodeRoot->left && !actionFileNodeRoot->right) { - // Nada que hacer return; } - // Iterar todos los nodos de la izquierda - if (actionFileNodeRoot->left) { - fileNodeLeft = actionFileNodeRoot->left->child; - while (fileNodeLeft) { - if (actionFileNodeRoot->right) { - fileNodeRight = actionFileNodeRoot->right->child; - while (fileNodeRight) { - if (!strcmp(fileNodeLeft->name, fileNodeRight->name)) { - break; - } else { - fileNodeRight = fileNodeRight->next; - } - } - } else { - fileNodeRight = NULL; - } - - CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue); - - fileNodeLeft = fileNodeLeft->next; - } - } - - // Iterar todos los nodos de la derecha, - // ignorando las comparaciones ya realizadas - if (actionFileNodeRoot->right) { + // There is no left part + if (!actionFileNodeRoot->left) { fileNodeRight = actionFileNodeRoot->right->child; while (fileNodeRight) { - int doCheck = 1; - if (actionFileNodeRoot->left) { - fileNodeLeft = actionFileNodeRoot->left->child; - while (fileNodeLeft) { - AccionFileNode *afnCheck = actionFileNodeQueueStart; - while (afnCheck) { - if (afnCheck->left == fileNodeLeft - && afnCheck->right == fileNodeRight) { - break; - } else { - afnCheck = afnCheck->next; - } - } - if (afnCheck) { - doCheck = 0; - break; - } - if (!strcmp(fileNodeLeft->name, fileNodeRight->name)) { - break; - } else { - fileNodeLeft = fileNodeLeft->next; - } - } - } else { - fileNodeLeft = NULL; - } - - if (doCheck) { - CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue); - } + CheckPair(NULL, fileNodeRight, actionFileNodeQueue); fileNodeRight = fileNodeRight->next; } + return; } + // There is no right part + if (!actionFileNodeRoot->right) { + fileNodeLeft = actionFileNodeRoot->left->child; + while (fileNodeLeft) { + + CheckPair(fileNodeLeft, NULL, actionFileNodeQueue); + + fileNodeLeft = fileNodeLeft->next; + } + return; + } + + // Prepare chains + fileNodeRightQueue = actionFileNodeRoot->right->child; + fileNodeRightProcessed = NULL; + + // Iterate left child FileNodes + fileNodeLeft = actionFileNodeRoot->left->child; + while (fileNodeLeft) { + fileNodeRightPrevious = NULL; + fileNodeRight = fileNodeRightQueue; + while (fileNodeRight) { + if(!strcmp(fileNodeLeft->name, fileNodeRight->name)){ + // Match, extract right child FileNode to the processed chain + if(fileNodeRightPrevious) { + fileNodeRightPrevious->next = fileNodeRight->next; + }else{ + fileNodeRightQueue = fileNodeRight->next; + } + fileNodeRight->next = fileNodeRightProcessed; + fileNodeRightProcessed = fileNodeRight; + + CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue); + break; + }else{ + // Next right child + fileNodeRightPrevious = fileNodeRight; + fileNodeRight = fileNodeRight->next; + } + } + if(!fileNodeRight){ + CheckPair(fileNodeLeft, NULL, actionFileNodeQueue); + } + fileNodeLeft = fileNodeLeft->next; + } + + // Iterate unprocessed right childs + fileNodeRight = fileNodeRightQueue; + while (fileNodeRight) { + CheckPair(NULL, fileNodeRight, actionFileNodeQueue); + fileNodeRightPrevious = fileNodeRight; + fileNodeRight = fileNodeRight->next; + fileNodeRightPrevious->next = fileNodeRightProcessed; + fileNodeRightProcessed = fileNodeRightPrevious; + } + actionFileNodeRoot->right->child = fileNodeRightProcessed; + } void AccionFileNode_DeletePair(FileNode *fileNodeLeft, FileNode *fileNodeRight,