Beispiel #1
0
/**
 * Deletes the requested node.
 *
 * @param node       node to be deleted
 */
static void
node_delete_aux(struct bst_node** node)
{
    /* TODO: For Step 2 you will have to make this function thread-safe */

    struct bst_node* old_node = *node;

    if ((*node)->left == NULL) {
        *node = (*node)->right; // Node is replaced by its RIGHT node
        free_node(old_node);
    } else if ((*node)->right == NULL) {
        *node = (*node)->left; // Node is replaced by its LEFT node
        free_node(old_node);
    } else {

        // Here we need to lock the node we are looking at AND its parent

        struct bst_node** pred = &(*node)->left; // pred is set to the LEFT node
	
        while ((*pred)->right != NULL) { // Find the most RIGHT node of pred
	    pred = &(*pred)->right;
	}

	/* Swap values */
	void* temp = (*pred)->data; // Set the value of NODE = NODE->LEFT->(most RIGHT node value) 
	(*pred)->data = (*node)->data; 
	(*node)->data = temp;

	node_delete_aux(pred); // Remove NODE->LEFT->(most RIGHT node) instead of NODE
    }
}
Beispiel #2
0
/**
 * Deletes the requested node.
 *
 * @param node       node to be deleted
 */
static void
node_delete_aux(struct bst_node** node)
{
    /* TODO: For Step 2 you will have to make this function thread-safe */

    struct bst_node* old_node = *node;

    if ((*node)->left == NULL) {
        *node = (*node)->right;
        free_node(old_node);
    } else if ((*node)->right == NULL) {
        *node = (*node)->left;
        free_node(old_node);
    } else {
        struct bst_node** pred = &(*node)->left;
	while ((*pred)->right != NULL) {
	    pred = &(*pred)->right;
	}

	/* Swap values */
	void* temp = (*pred)->data;
	(*pred)->data = (*node)->data;
	(*node)->data = temp;

	node_delete_aux(pred);
    }
}
Beispiel #3
0
/**
 * Deletes the node which points to the requested data.
 *
 * @param root       root of the tree
 * @param comparator function used to compare nodes
 * @param data       pointer to the data to be deleted
 * @return           1 if data is not found, 0 otherwise
 */
int
node_delete(struct bst_node** root, comparator compare, void* data)
{
    struct bst_node** node = search(root, compare, data);

    if (*node == NULL)
        return -1;

    node_delete_aux(node);

    return 0;
}
Beispiel #4
0
/**
 * Deletes the node which points to the requested data.
 *
 * Should be safe when called in parallel with other threads that
 * might call the same functions. Uses fine grained locking.
 *
 * @param root       root of the tree
 * @param comparator function used to compare nodes
 * @param data       pointer to the data to be deleted
 * @return           1 if data is not found, 0 otherwise
 */
int
node_delete_ts_fg(struct bst_node** root, comparator compare, void* data)
{
    /* TODO: Fill-in the body of this function */
    struct bst_node** node = search(root, compare, data); //find node to delete

    if (*node == NULL)
        return -1;

    node_delete_aux(node); //delete node
    return 0;
}
Beispiel #5
0
/**
 * Deletes the node which points to the requested data.
 *
 * Should be safe when called in parallel with other threads that
 * might call the same functions. Uses fine grained locking.
 *
 * @param root       root of the tree
 * @param comparator function used to compare nodes
 * @param data       pointer to the data to be deleted
 * @return           1 if data is not found, 0 otherwise
 */
int
node_delete_ts_cg(struct bst_node** root, comparator compare, void* data)
{
    /* TODO: Fill-in the body of this function */

    assert(pthread_mutex_lock(&mutexCG) == 0); //lock mutexCG

    struct bst_node** node = search(root, compare, data); //find the node (if any) to delete
    node_delete_aux(node);

    assert(pthread_mutex_unlock(&mutexCG) == 0); //unlock mutexCG
    return 0;
}
Beispiel #6
0
/**
 * Deletes the node which points to the requested data.
 *
 * Should be safe when called in parallel with other threads that
 * might call the same functions. Uses fine grained locking.
 *
 * @param root       root of the tree
 * @param comparator function used to compare nodes
 * @param data       pointer to the data to be deleted
 * @return           1 if data is not found, 0 otherwise
 */
int
node_delete_ts_fg(struct bst_node** root, comparator compare, void* data)
{
    /* TODO: Fill-in the body of this function */
    struct bst_node** node = search(root, compare, data);
    
    if (node == NULL)
        return -1;
    else 
    {   
        node_delete_aux(node);
        return 0;
    }
}
Beispiel #7
0
static void
fg_node_delete_aux(struct bst_node** node)
{
    /* TODO: For Step 2 you will have to make this function thread-safe */
    
    struct bst_node* old_node = *node;
    
    if ((*node)->left == NULL) {
        if((*node)->right != NULL) {
            pthread_mutex_lock(&(*node)->right->fg_mutex);
        }
        *node = (*node)->right;
        pthread_mutex_unlock(&old_node->fg_mutex);
        free_node(old_node);
        if((*node) != NULL) {
            pthread_mutex_unlock(&(*node)->fg_mutex); 
        }
    } else if ((*node)->right == NULL) {
        if((*node)->left != NULL) {
            pthread_mutex_lock(&(*node)->left->fg_mutex); 
        }
        *node = (*node)->left;
        pthread_mutex_unlock(&old_node->fg_mutex);
        free_node(old_node);
        if((*node) != NULL) { 
            pthread_mutex_unlock(&(*node)->fg_mutex); 
        }
    } else {
        pthread_mutex_lock(&(*node)->left->fg_mutex);
        struct bst_node** pred = &(*node)->left;
        struct bst_node** pred_temp = pred;
        while ((*pred)->right != NULL) { 
            pthread_mutex_lock(&(*pred)->right->fg_mutex); 
            pred = &(*pred)->right;
            pthread_mutex_unlock(&(*pred_temp)->fg_mutex);
            pred_temp = pred;
	}
        
	/* Swap values */
	void* temp = (*pred)->data;
	(*pred)->data = (*node)->data;
	(*node)->data = temp;
        
        pthread_mutex_unlock(&old_node->fg_mutex);
        
	node_delete_aux(pred);
    }
    
}
Beispiel #8
0
/**
 * Deletes the node which points to the requested data.
 *
 * Should be safe when called in parallel with other threads that
 * might call the same functions. Uses fine grained locking.
 *
 * @param root       root of the tree
 * @param comparator function used to compare nodes
 * @param data       pointer to the data to be deleted
 * @return           1 if data is not found, 0 otherwise
 */
int
node_delete_ts_cg(struct bst_node** root, comparator compare, void* data)
{
    /* TODO: Fill-in the body of this function */

    pthread_mutex_lock(&mutexCG);
    struct bst_node** node = search(root, compare, data);
    if (*node == NULL){
        pthread_mutex_unlock(&mutexCG);
        return -1;
    }
    else {
        node_delete_aux(node);
        pthread_mutex_unlock(&mutexCG);
        return 0;
    }
}
Beispiel #9
0
/**
 * Deletes the requested node.
 *
 * @param node       node to be deleted
 */
static void
node_delete_aux(struct bst_node** node)
{
    /* TODO: For Step 2 you will have to make this function thread-safe */
    // vi vet att vi är i rätt nod
    struct bst_node* old_node = *node;

    // kolla om vänster barn existerar
    if ((*node)->left == NULL) {
        // eftersom vänster barn inte finns kan vi använda höger barn
        *node = (*node)->right;
        free_node(old_node);
        // Vänster Barn Finns och höger finns inte
    } else if ((*node)->right == NULL) {
        // swap till vänster barn
        *node = (*node)->left;
        free_node(old_node);
        /*********************************************/
        if(*parent != NULL)
            assert(pthread_mutex_unlock(&(*parent)->mutexNODE) == 0);
        /*********************************************/ 
    } else {
        // vi vet att båda barn finns, vi måste alltså gå ett steg till
        // vänster och gå längst ner i dess högerbarn
        struct bst_node** pred = &(*node)->left;
	while ((*pred)->right != NULL) {
	    pred = &(*pred)->right;
	}
        

	/* Swap values */
	void* temp = (*pred)->data;
	(*pred)->data = (*node)->data;
	(*node)->data = temp;
        assert(pthread_mutex_unlock(&(*parent)->mutexNODE) == 0);
        // vi har bytt info, och skall ta bort temp barnet men gör det
        // rekursivt eftersom den kan ha vänsterbarn
        node_delete_aux(pred);
        assert(pthread_mutex_unlock(&(*node)->mutexNODE) == 0);    
    }
}
Beispiel #10
0
//pthread_spinlock_t cg_spin;
int
node_delete_ts_cg(struct bst_node** root, comparator compare, void* data)
{
    /* TODO: Fill-in the body of this function */
    if(pthread_mutex_lock(&cg_mutex) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
    //if(pthread_spin_lock(&cg_spin) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
    struct bst_node** node = search(root, compare, data);
    
    if (node == NULL) {
        //if(pthread_spin_unlock(&cg_spin) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
        if(pthread_mutex_unlock(&cg_mutex) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
        return -1;
    }
    
    node_delete_aux(node);
    
    //if(pthread_spin_unlock(&cg_spin) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
    if(pthread_mutex_unlock(&cg_mutex) != 0) { perror("ERROR: "); exit(EXIT_FAILURE); }
    
    return 0;
}