static void _cache__add__fringe(SG_context * pCtx, SG_dagfrag * pFrag, const char* psz_id) { _my_data * pDataAllocated = NULL; _my_data * pDataCached = NULL; _my_data * pOldData = NULL; SG_NULLARGCHECK_RETURN(pFrag); // this is probably not necessary for an internal routine SG_NONEMPTYCHECK_RETURN(psz_id); // this is probably not necessary for an internal routine SG_ERR_CHECK( SG_alloc(pCtx, 1, sizeof(_my_data), &pDataAllocated) ); pDataAllocated->m_genDagnode = 0; pDataAllocated->m_state = SG_DFS_END_FRINGE; pDataAllocated->m_pDagnode = NULL; SG_ERR_CHECK( SG_rbtree__update__with_assoc(pCtx,pFrag->m_pRB_Cache,psz_id,pDataAllocated,(void **)&pOldData) ); pDataCached = pDataAllocated; pDataAllocated = NULL; // cache now owns pData and pDagnode. SG_ASSERT_RELEASE_RETURN2( (!pOldData), (pCtx,"Possible memory leak adding [%s] to dagfrag fringe.",psz_id) ); return; fail: // TODO is the following test and assignment really necessary? or did it get carried // TODO over from another change? we weren't given a pDagnode in the first place. if (pDataCached) // caller still owns pDagnode on errors even if we got pData pDataCached->m_pDagnode = NULL; // into the cache. This may cause problems later if you keep going. SG_ERR_IGNORE( _my_data__free(pCtx, pDataAllocated) ); // free pData if we did not get it stuck into the cache. }
void SG_rbtree_ui64__update__with_assoc( SG_context* pCtx, SG_rbtree_ui64* prb, SG_uint64 ui64_key, void* assoc, void** pOldAssoc ) { sg_buf_ui64 bufUI64; (void)SG_hex__format_uint64(bufUI64, ui64_key); SG_ERR_CHECK_RETURN( SG_rbtree__update__with_assoc(pCtx, (SG_rbtree *)prb, bufUI64, assoc, pOldAssoc) ); }
static void _cache__add__dagnode(SG_context * pCtx, SG_dagfrag * pFrag, SG_int32 gen, SG_dagnode * pDagnode, // if successful, we take ownership of dagnode SG_uint32 state, _my_data ** ppData) // we retain ownership of DATA (but you may modify non-pointer values within it) { const char * szHid; _my_data * pDataAllocated = NULL; _my_data * pDataCached = NULL; _my_data * pOldData = NULL; SG_NULLARGCHECK_RETURN(pFrag); // this is probably not necessary for an internal routine SG_NULLARGCHECK_RETURN(pDagnode); // this is probably not necessary for an internal routine SG_ERR_CHECK_RETURN( SG_dagnode__get_id_ref(pCtx,pDagnode,&szHid) ); SG_ASSERT_RELEASE_RETURN2( (SG_DFS_END_FRINGE != state), (pCtx,"Adding end-fringe dagnode [%s] to dagfrag.",szHid) ); SG_ERR_CHECK( SG_alloc(pCtx, 1, sizeof(_my_data), &pDataAllocated) ); pDataAllocated->m_genDagnode = gen; pDataAllocated->m_state = state; SG_ERR_CHECK( SG_rbtree__update__with_assoc(pCtx,pFrag->m_pRB_Cache,szHid,pDataAllocated,(void **)&pOldData) ); SG_ASSERT_RELEASE_FAIL2( (!pOldData), (pCtx,"Possible memory leak adding [%s] to dagfrag.",szHid) ); // if everything is successful, the cache now owns pData and pDagnode. pDataCached = pDataAllocated; pDataAllocated = NULL; pDataCached->m_pDagnode = pDagnode; if (ppData) *ppData = pDataCached; return; fail: if (pDataCached) // caller still owns pDagnode on errors even if we got pData pDataCached->m_pDagnode = NULL; // into the cache. This may cause problems later if you keep going. SG_ERR_IGNORE( _my_data__free(pCtx, pDataAllocated) ); // free pData if we did not get it stuck into the cache. }
static void _sg_dagfrag__my_create_generation_sorted_member_cache_callback(SG_context * pCtx, const char * szKey, void * pAssocData, void * pVoidFrag) { // a standard SG_rbtree_foreach_callback. // // insert a parallel item in the SORTED CACHE for this item from the regular CACHE. // we only want items of type START_MEMBER and INTERIOR_MEMBER in our sorted cache. _my_data * pMyData = (_my_data *)pAssocData; SG_dagfrag * pFrag = (SG_dagfrag *)pVoidFrag; char bufSortKey[SG_HID_MAX_BUFFER_LENGTH + 20]; switch (pMyData->m_state) { default: //case SG_DFS_UNKNOWN: //case SG_DFS_END_FRINGE: return; case SG_DFS_START_MEMBER: case SG_DFS_INTERIOR_MEMBER: break; } // the sort key looks like <generation>.<hid> "%08lx.%s" SG_ERR_CHECK_RETURN( SG_sprintf(pCtx, bufSortKey,SG_NrElements(bufSortKey), "%08lx.%s", pMyData->m_genDagnode,szKey) ); SG_ERR_CHECK_RETURN( SG_rbtree__update__with_assoc(pCtx, pFrag->m_pRB_GenerationSortedMemberCache,bufSortKey,pMyData,NULL) ); }