static inline void attr_delete_from_vhash(SV *self, SV *value) { hrattr_simple *attr = attr_from_sv(SvRV((self))); //UN_del_action(value, SvRV(self)); SV *vaddr = newSVuv((UV)SvRV(value)); SV *rlookup; SV *vhash; char *astr = attr_strkey(attr, attr_getsize(attr)); get_hashes((HR_Table_t)attr_parent_tbl(attr), HR_HKEY_LOOKUP_REVERSE, &rlookup, HR_HKEY_LOOKUP_NULL); vhash = get_vhash_from_rlookup(rlookup, vaddr, 0); U32 old_refcount = refcnt_ka_begin(value); if(vhash) { HR_DEBUG("vhash has %d keys", HvKEYS(REF2HASH(vhash))); HR_DEBUG("Deleting '%s' from vhash=%p", astr, SvRV(vhash)); hv_delete(REF2HASH(vhash), astr, strlen(astr), G_DISCARD); if(!HvKEYS(REF2HASH(vhash))) { HR_DEBUG("Vhash empty"); HR_PL_del_action_container(value, rlookup); hv_delete_ent(REF2HASH(rlookup), vaddr, G_DISCARD, 0); } else { HR_DEBUG("Vhash still has %d keys", HvKEYS(REF2HASH(vhash))); } } refcnt_ka_end(value, old_refcount); }
int main() { std::vector<int> values; values.push_back(10); values.push_back(20); std::vector<std::size_t> hashes = get_hashes(values); assert(hashes[0] = boost::hash<int>()(values[0])); assert(hashes[1] = boost::hash<int>()(values[1])); }
void HRXSATTR_ithread_predup(SV *self, SV *table, HV *ptr_map) { hrattr_simple *attr = attr_from_sv(SvRV(self)); /*Make sure our attribute hash is visible to perl space*/ SV *attrhash_ref; RV_Newtmp(attrhash_ref, (SV*)attr->attrhash); hr_dup_store_rv(ptr_map, attrhash_ref); RV_Freetmp(attrhash_ref); char *ktmp; I32 tmplen; SV *vtmp; SV *rlookup; get_hashes(REF2TABLE(table), HR_HKEY_LOOKUP_REVERSE, &rlookup, HR_HKEY_LOOKUP_NULL); hv_iterinit(attr->attrhash); while( (vtmp = hv_iternextsv(attr->attrhash, &ktmp, &tmplen))) { HR_Dup_Vinfo *vi = hr_dup_get_vinfo(ptr_map, SvRV(vtmp), 1); if(!vi->vhash) { SV *vaddr = newSVuv((UV)SvRV(vtmp)); SV *vhash = get_vhash_from_rlookup(rlookup, vaddr, 0); vi->vhash = vhash; SvREFCNT_dec(vaddr); } } if(attr->encap) { hrattr_encap *aencap = attr_encap_cast(attr); hr_dup_store_rv(ptr_map, aencap->obj_rv); char *ai = (char*)hr_dup_store_kinfo( ptr_map, HR_DUPKEY_AENCAP, aencap->obj_paddr, 1); if(SvWEAKREF(aencap->obj_rv)) { *ai = HRK_DUP_WEAK_ENCAP; } else { *ai = 0; } } }
static void attr_destroy_trigger(SV *self_sv, SV *encap_obj, HR_Action *action_list) { HR_DEBUG("self_sv=%p", self_sv); HR_DEBUG("Attr destroy hook"); HR_DEBUG("We are ATTR=%p", self_sv); //sv_dump(self_sv); hrattr_simple *attr = attr_from_sv(self_sv); HR_DEBUG("hrattr=%p", attr); HR_Table_t parent = attr_parent_tbl(attr); HR_DEBUG("Parent=%p", parent); SV *rlookup = NULL, *attr_lookup = NULL; if(SvREFCNT(parent)) { get_hashes(parent, HR_HKEY_LOOKUP_REVERSE, &rlookup, HR_HKEY_LOOKUP_ATTR, &attr_lookup, HR_HKEY_LOOKUP_NULL); HR_DEBUG("rlookup=%p, attr_lookup=%p", rlookup, attr_lookup); } else { HR_DEBUG("Main lookup table being destroyed?"); parent = NULL; } char *ktmp; int attrsz = attr_getsize(attr); SV *vtmp, *vhash; I32 tmplen; mk_ptr_string(oaddr, self_sv); int oaddr_len = strlen(oaddr); SV *attrhash_ref = NULL, *self_ref = NULL; RV_Newtmp( attrhash_ref, ((SV*)attr->attrhash) ); RV_Newtmp( self_ref, self_sv ); if(action_list) { while( (HR_nullify_action(action_list, (SV*)&attr_destroy_trigger, NULL, HR_KEY_TYPE_NULL|HR_KEY_SFLAG_HASHREF_OPAQUE) == HR_ACTION_DELETED) ); /*No body*/ } else { HR_PL_del_action_container(self_ref, (SV*)&attr_destroy_trigger); } HR_DEBUG("Deleted self destroy hook"); if(attr->encap) { hrattr_encap *aencap = (hrattr_encap*)attr; if(aencap->obj_paddr) { SV *encap_ref = NULL; RV_Newtmp(encap_ref, (SV*)aencap->obj_paddr); HR_PL_del_action_container(encap_ref, (SV*)&encap_attr_destroy_hook); RV_Freetmp(encap_ref); HR_DEBUG("Deleted encap destroy hook"); } if(aencap->obj_rv) { SvREFCNT_dec( aencap->obj_rv ); } } if(attr_lookup) { HR_DEBUG("Deleting our attr_lookup entry.."); hv_delete(REF2HASH(attr_lookup), attr_strkey(attr, attrsz), strlen(attr_strkey(attr, attrsz)), G_DISCARD); HR_DEBUG("attr_lookup entry deleted"); } U32 old_refcount = refcnt_ka_begin(self_sv); I32 attrvals = hv_iterinit(attr->attrhash); HR_DEBUG("We have %d values", attrvals); while( (vtmp = hv_iternextsv(attr->attrhash, &ktmp, &tmplen)) ) { SV *vptr, *vref; sscanf(ktmp, "%lu", &vptr); /*Don't ask.. also, uses slightly less memory*/ RV_Newtmp(vref, vptr); U32 old_v_refcount = refcnt_ka_begin(vptr); attr_delete_value_from_attrhash(self_ref, vref); if(SvROK(vref) && parent) { HR_DEBUG("Deleting vhash entry"); attr_delete_from_vhash(self_ref, vref); } else { HR_DEBUG("Eh?"); } RV_Freetmp(vref); refcnt_ka_end(vptr, old_v_refcount); } SvREFCNT_dec(attr->attrhash); RV_Freetmp(self_ref); RV_Freetmp(attrhash_ref); refcnt_ka_end(self_sv, old_refcount); HR_DEBUG("Attr destroy done"); }
static inline SV* attr_get(SV *self, SV *attr, char *t, int options) { char *attr_ustr = NULL, *attr_fullstr = NULL; char smallbuf[128] = { '\0' }; char ptr_buf[128] = { '\0' }; SV *kt_lookup, *attr_lookup; SV **kt_ent; SV *aobj = NULL; SV **a_ent; SV *my_stashcache_ref; HR_BlessParams stash_params; int attrlen = 0; int on_heap = 0; int prefix_len = 0; get_hashes(REF2TABLE(self), HR_HKEY_LOOKUP_ATTR, &attr_lookup, HR_HKEY_LOOKUP_KT, &kt_lookup, HR_HKEY_LOOKUP_PRIVDATA, &my_stashcache_ref, HR_HKEY_LOOKUP_NULL ); blessparam_init(stash_params); if(! (kt_ent = hv_fetch(REF2HASH(kt_lookup), t, strlen(t), 0))) { die("Couldn't determine keytype '%s'", t); } attrlen = strlen(SvPV_nolen(*kt_ent)) + 1; if(SvROK(attr)) { attrlen += sprintf(ptr_buf, "%lu", SvRV(attr)); attr_ustr = ptr_buf; } else { attrlen += strlen(SvPV_nolen(attr)); attr_ustr = SvPV_nolen(attr); } attrlen += sizeof(HR_PREFIX_DELIM) - 1; if(attrlen > 128) { on_heap = 1; Newx(attr_fullstr, attrlen, char); } else { attr_fullstr = smallbuf; } *attr_fullstr = '\0'; sprintf(attr_fullstr, "%s%s%s", SvPV_nolen(*kt_ent), HR_PREFIX_DELIM, attr_ustr); HR_DEBUG("ATTRKEY=%s", attr_fullstr); a_ent = hv_fetch(REF2HASH(attr_lookup), attr_fullstr, attrlen-1, 0); if(!a_ent) { prefix_len = strlen(t); if( (options & STORE_OPT_O_CREAT) == 0) { HR_DEBUG("Could not locate attribute and O_CREAT not specified"); goto GT_RET; } else if(SvROK(attr)) { blessparam_setstash(stash_params, stash_from_cache_nocheck(my_stashcache_ref, HR_STASH_ATTR_ENCAP)); aobj = attr_encap_new(blessparam2chrp(stash_params), attr_fullstr, attr, self); if( (options & STORE_OPT_STRONG_KEY) == 0) { sv_rvweaken( ((hrattr_encap*)attr_from_sv(SvRV(aobj)))->obj_rv ); } } else { blessparam_setstash(stash_params, stash_from_cache_nocheck(my_stashcache_ref,HR_STASH_ATTR_SCALAR)); aobj = attr_simple_new(blessparam2chrp(stash_params), attr_fullstr, self); } a_ent = hv_store(REF2HASH(attr_lookup), attr_fullstr, attrlen-1, newSVsv(aobj), 0); /*Actual attribute entry is ALWAYS weak and is entirely dependent on vhash entries*/ (attr_from_sv(SvRV(aobj)))->prefix_len = prefix_len; assert(a_ent); sv_rvweaken(*a_ent); } else { aobj = *a_ent; } GT_RET: if(on_heap) { Safefree(attr_fullstr); } HR_DEBUG("Returning %p", aobj); return aobj; }