src/imap/imap.c
/*
 * Map 'dest' will be the symmetric difference between the two maps. Map 'imap'
 * will be destroyed so it cannot be used anymore.
 *
 * This function can call 'decref_cb' when an item is removed from the map.
 * We only call the function for sure when the item is removed from both maps.
 * When we are sure the item still exists in the 'dest' map and is only removed
 * from the 'imap', we simply decrement the ref counter.
 */
Map 'dest' will be the symmetric difference between the two maps. Map 'imap'
will be destroyed so it cannot be used anymore.

This function can call 'decref_cb' when an item is removed from the map.
We only call the function for sure when the item is removed from both maps.
When we are sure the item still exists in the 'dest' map and is only removed
from the 'imap', we simply decrement the ref counter.
Map ' dest ' will be the symmetric difference between the two maps . Map ' imap ' will be destroyed so it cannot be used anymore . This function can call ' decref_cb ' when an item is removed from the map . We only call the function for sure when the item is removed from both maps . When we are sure the item still exists in the ' dest ' map and is only removed from the ' imap ' we simply decrement the ref counter .
void imap_symmetric_difference_ref(
        imap_t * dest,
        imap_t * imap,
        imap_free_cb decref_cb)
{
    if (dest->slist != NULL)
    {
        slist_free(dest->slist);
        dest->slist = NULL;
    }
    if (imap->len)
    {
        imap_node_t * dest_nd;
        imap_node_t * imap_nd;
        for (uint_fast8_t i = 0; i < IMAP_NODE_SZ; i++)
        {
            dest_nd = dest->nodes + i;
            imap_nd = imap->nodes + i;
            if (imap_nd->data != NULL)
            {
                if (dest_nd->data != NULL)
                {
#ifdef DEBUG
                    assert (imap_nd->data == dest_nd->data);
#endif
                    slist_object_decref(dest_nd->data);
                    (*decref_cb)(imap_nd->data);
                    dest_nd->data = NULL;
                    dest->len--;
                }
                else
                {
                    dest_nd->data = imap_nd->data;
                    dest->len++;
                }
            }
            if (imap_nd->nodes != NULL)
            {
                if (dest_nd->nodes != NULL)
                {
                    size_t tmp = dest_nd->size;
                    IMAP_symmetric_difference_ref(
                            dest_nd,
                            imap_nd,
                            decref_cb);
                    dest->len += dest_nd->size - tmp;
                }
                else
                {
                    dest_nd->nodes = imap_nd->nodes;
                    dest_nd->size = imap_nd->size;
                    dest->len += dest_nd->size;
                }
            }
        }
    }
    slist_free(imap->slist);
    free(imap);
}
void imap_symmetric_difference_ref ( imap_t * dest , imap_t * imap , imap_free_cb decref_cb ) { if ( dest -> slist != NULL ) { slist_free ( dest -> slist ) ; dest -> slist = NULL ; } if ( imap -> len ) { imap_node_t * dest_nd ; imap_node_t * imap_nd ; for ( uint_fast8_t i = 0 ; i < IMAP_NODE_SZ ; i ++ ) { dest_nd = dest -> nodes + i ; imap_nd = imap -> nodes + i ; if ( imap_nd -> data != NULL ) { if ( dest_nd -> data != NULL ) { #ifdef DEBUG assert ( imap_nd -> data == dest_nd -> data ) ; #endif slist_object_decref ( dest_nd -> data ) ; ( * decref_cb ) ( imap_nd -> data ) ; dest_nd -> data = NULL ; dest -> len -- ; } else { dest_nd -> data = imap_nd -> data ; dest -> len ++ ; } } if ( imap_nd -> nodes != NULL ) { if ( dest_nd -> nodes != NULL ) { size_t tmp = dest_nd -> size ; IMAP_symmetric_difference_ref ( dest_nd , imap_nd , decref_cb ) ; dest -> len += dest_nd -> size - tmp ; } else { dest_nd -> nodes = imap_nd -> nodes ; dest_nd -> size = imap_nd -> size ; dest -> len += dest_nd -> size ; } } } } slist_free ( imap -> slist ) ; free ( imap ) ; }
Map 'dest' will be the symmetric difference between the two maps.
Map ' dest ' will be the symmetric difference between the two maps .
/* this must be the same object */ /* we are sure to have one ref left */ /* but now we are not sure anymore */ /* cleanup source imap */