src/imap/imap.c
/*
 * Map 'dest' will be the intersection 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 intersection 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 intersection 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_intersection_ref(
        imap_t * dest,
        imap_t * imap,
        imap_free_cb decref_cb)
{
    if (dest->slist != NULL)
    {
        slist_free(dest->slist);
        dest->slist = NULL;
    }
    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)
        {
            (*decref_cb)(imap_nd->data);
        }
        else if (dest_nd->data != NULL)
        {
            (*decref_cb)(dest_nd->data);
            dest_nd->data = NULL;
            dest->len--;
        }
        if (imap_nd->nodes != NULL)
        {
            if (dest_nd->nodes != NULL)
            {
                size_t tmp = dest_nd->size;
                IMAP_intersection_ref(dest_nd, imap_nd, decref_cb);
                dest->len -= tmp - dest_nd->size;
            }
            else
            {
                IMAP_node_free_cb(imap_nd, decref_cb);
            }
        }
        else if (dest_nd->nodes != NULL)
        {
            dest->len -= dest_nd->size;
            IMAP_node_free_cb(dest_nd, decref_cb);
            dest_nd->nodes = NULL;
        }
    }
    slist_free(imap->slist);
    free(imap);
}
void imap_intersection_ref ( imap_t * dest , imap_t * imap , imap_free_cb decref_cb ) { if ( dest -> slist != NULL ) { slist_free ( dest -> slist ) ; dest -> slist = NULL ; } 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 ) { ( * decref_cb ) ( imap_nd -> data ) ; } else if ( dest_nd -> data != NULL ) { ( * decref_cb ) ( dest_nd -> data ) ; dest_nd -> data = NULL ; dest -> len -- ; } if ( imap_nd -> nodes != NULL ) { if ( dest_nd -> nodes != NULL ) { size_t tmp = dest_nd -> size ; IMAP_intersection_ref ( dest_nd , imap_nd , decref_cb ) ; dest -> len -= tmp - dest_nd -> size ; } else { IMAP_node_free_cb ( imap_nd , decref_cb ) ; } } else if ( dest_nd -> nodes != NULL ) { dest -> len -= dest_nd -> size ; IMAP_node_free_cb ( dest_nd , decref_cb ) ; dest_nd -> nodes = NULL ; } } slist_free ( imap -> slist ) ; free ( imap ) ; }
Map 'dest' will be the intersection between the two maps.
Map ' dest ' will be the intersection between the two maps .
/* cleanup source imap */