Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
bool
LUCY_Doc_Equals_IMP(lucy_Doc *self, cfish_Obj *other) {
    if ((lucy_Doc*)other  == self)        { return true;  }
    if (!cfish_Obj_is_a(other, LUCY_DOC)) { return false; }
    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
    lucy_DocIVARS *const ovars = lucy_Doc_IVARS((lucy_Doc*)other);

    if (!ivars->doc_id == ovars->doc_id)   { return false; }
    if (!!ivars->fields ^ !!ovars->fields) { return false; }

    // Verify fields.  Don't allow any deep data structures.
    dTHX;
    HV *my_fields    = (HV*)ivars->fields;
    HV *other_fields = (HV*)ovars->fields;
    if (HvKEYS(my_fields) != HvKEYS(other_fields)) { return false; }
    I32 num_fields = hv_iterinit(my_fields);
    while (num_fields--) {
        HE *my_entry = hv_iternext(my_fields);
        SV *my_val_sv = HeVAL(my_entry);
        STRLEN key_len;
        char *key;

        if (HeKLEN(my_entry) == HEf_SVKEY) {
            SV *key_sv = HeKEY_sv(my_entry);
            key = SvPV(key_sv, key_len);
            if (SvUTF8(key_sv)) { key_len = -key_len; }
        }
        else {
            key_len = HeKLEN(my_entry);
            key = key_len ? HeKEY(my_entry) : Nullch;
            if (HeKUTF8(my_entry)) { key_len = -key_len; }
        }

        SV **const other_val = hv_fetch(other_fields, key, key_len, 0);
        if (!other_val) { return false; }
        if (!sv_eq(my_val_sv, *other_val)) { return false; }
    }

    return true;
}
Ejemplo n.º 3
0
uint32_t
lucy_Doc_get_size(lucy_Doc *self) {
    return self->fields ? HvKEYS((HV*)self->fields) : 0;
}
Ejemplo n.º 4
0
void HRA_store_a(SV *self, SV *attr, char *t, SV *value, ...)
{
    SV *vstring = newSVuv((UV)SvRV(value)); //reverse lookup key
    SV *aobj    = NULL; //primary attribute entry, from attr_lookup
    SV *vref    = NULL; //value's entry in attribute hash
    SV *attrhash_ref = NULL; //reference for attribute hash, for adding actions
    
    SV **a_r_ent = NULL; //lval-type HE for looking/storing attr in vhash
    char *astring = NULL;
    
    hrattr_simple *aptr; //our private attribute structure
    
    int options = STORE_OPT_O_CREAT;
    int i;
    
    dXSARGS;
    if ((items-4) % 2) {
        die("Expected hash options or nothing (got %d)", items-3);
    }
    for(i=4;i<items;i+=2) {
        _chkopt(STRONG_ATTR, i, options);
        _chkopt(STRONG_VALUE, i, options);
    }
    
    aobj = attr_get(self, attr, t, options);
    if(!aobj) {
        die("attr_get() failed to return anything");
    }
    
    aptr = attr_from_sv(SvRV(aobj));
    assert(SvROK(aobj));
    astring = attr_strkey(aptr, attr_getsize(aptr));
    
    if(!insert_into_vhash(value, aobj, astring, REF2TABLE(self), NULL)) {
        goto GT_RET; /*No new insertions*/
    }
    
    if(!HvKEYS(aptr->attrhash)) {
        /*First entry and we've already inserted our reverse entry*/
        SvREFCNT_dec(SvRV(aobj));
    }
    
    vref = newSVsv(value);
    if(hv_store_ent(aptr->attrhash, vstring, vref, 0)) {
        if( (options & STORE_OPT_STRONG_VALUE) == 0) {
            sv_rvweaken(vref);
        }
    } else {
        SvREFCNT_dec(vref);
    }
    
    RV_Newtmp(attrhash_ref, (SV*)aptr->attrhash);
    
    HR_Action v_actions[] = {
        HR_DREF_FLDS_ptr_from_hv(SvRV(value), attrhash_ref),
        HR_ACTION_LIST_TERMINATOR
    };
    
    HR_add_actions_real(value, v_actions);
        
    GT_RET:
    SvREFCNT_dec(vstring);
    if(attrhash_ref) {
        RV_Freetmp(attrhash_ref);
    }
    XSRETURN(0);
}
Ejemplo n.º 5
0
Archivo: Doc.c Proyecto: gitpan/Lucy
uint32_t
LUCY_Doc_Get_Size_IMP(lucy_Doc *self) {
    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
    return ivars->fields ? HvKEYS((HV*)ivars->fields) : 0;
}