int redis_readdir_namespace(char * path, void *buf, fuse_fill_dir_t filler) { TCMAP *map; TCLISTDATUM *tcld; TCLIST * tcl; int ret = -ENOENT, i; struct stat st; char pathbuf[1024]; xlog("redis_readdir_namespace", "path=%s\n", path); if(!buf || !filler) return ret; memset(pathbuf,0,sizeof(pathbuf)); snprintf(pathbuf,sizeof(pathbuf)-1,"%s",path); map = redis_keys_to_tcmap(redis_dir_to_namespace(pathbuf,'/','*')); if(!map) return ret; tcl = tcmapvals(map); if(!tcl) return ret; xlog("redis_readdir_namespace", "anum=%i start=%i num=%i\n", tcl->anum, tcl->start, tcl->num); for(i=tcl->start;i<tcl->num;i++) { memset(&st,0,sizeof(st)); tcld = &tcl->array[i]; filler(buf, redis_dir_to_namespace((char *)tcld->ptr,'*','/'), &st, 0); } tclistclear(tcl); tcmapclear(map); return 0; }
/* Remove all records of a word database object. */ bool tcwdbvanish(TCWDB *wdb){ assert(wdb); if(!tcwdblockmethod(wdb, true)) return false; if(!wdb->open || !wdb->cc){ tcbdbsetecode(wdb->idx, TCEINVALID, __FILE__, __LINE__, __func__); tcwdbunlockmethod(wdb); return false; } bool err = false; tcmapclear(wdb->cc); tcmapclear(wdb->dtokens); if(!tcwdbmemsync(wdb, 1)) err = true; if(!tcbdbvanish(wdb->idx)) err = true; tcwdbunlockmethod(wdb); return !err; }
/* process a record in iteration of a query result set */ static int tcprocrec(const void *pkbuf, int pksiz, TCMAP *cols, TCPROCOP *procop){ JNIEnv *env = procop->env; jbyteArray pkey = (*env)->NewByteArray(env, pksiz); (*env)->SetByteArrayRegion(env, pkey, 0, pksiz, (jbyte *)pkbuf); jobject map = procop->map; (*env)->CallVoidMethod(env, map, procop->midmapclear); tcmapiterinit(cols); const char *nbuf; int nsiz; while((nbuf = tcmapiternext(cols, &nsiz)) != NULL){ int vsiz; const char *vbuf = tcmapiterval(nbuf, &vsiz); jstring name = (*env)->NewStringUTF(env, nbuf); if(!name){ throwoutmem(env); return TDBQPSTOP; } jbyteArray value = (*env)->NewByteArray(env, vsiz); if(!value){ throwoutmem(env); return TDBQPSTOP; } (*env)->SetByteArrayRegion(env, value, 0, vsiz, (jbyte *)vbuf); (*env)->CallObjectMethod(env, map, procop->midmapput, name, value); (*env)->DeleteLocalRef(env, value); (*env)->DeleteLocalRef(env, name); } int flags = (*env)->CallIntMethod(env, procop->obj, procop->mid, pkey, map); if((*env)->ExceptionOccurred(env) != NULL) flags = TDBQPSTOP; if(flags & TDBQPPUT){ tcmapclear(cols); jclass clsstring = procop->clsstring; jclass clsbyteary = procop->clsbyteary; jobject set = (*env)->CallObjectMethod(env, map, procop->midmapentryset); jobject iter = (*env)->CallObjectMethod(env, set, procop->midsetiterator); while((*env)->CallBooleanMethod(env, iter, procop->miditerhasnext)){ jobject entry = (*env)->CallObjectMethod(env, iter, procop->miditernext); jobject name = (*env)->CallObjectMethod(env, entry, procop->midentrygk); jobject value = (*env)->CallObjectMethod(env, entry, procop->midentrygv); if((*env)->IsInstanceOf(env, name, clsstring)){ jobject nary = (*env)->CallObjectMethod(env, name, procop->midstringgb); (*env)->DeleteLocalRef(env, name); name = nary; } if((*env)->IsInstanceOf(env, value, clsstring)){ jobject vary = (*env)->CallObjectMethod(env, value, procop->midstringgb); (*env)->DeleteLocalRef(env, value); value = vary; } if(!(*env)->IsInstanceOf(env, name, clsbyteary) || !(*env)->IsInstanceOf(env, value, clsbyteary)){ throwillarg(env); return TDBQPSTOP; } jboolean icn; jbyte *nbuf = (*env)->GetByteArrayElements(env, name, &icn); if(!nbuf){ throwoutmem(env); return TDBQPSTOP; } int nsiz = (*env)->GetArrayLength(env, name); jboolean icv; jbyte *vbuf = (*env)->GetByteArrayElements(env, value, &icv); if(!vbuf){ throwoutmem(env); return TDBQPSTOP; } int vsiz = (*env)->GetArrayLength(env, value); tcmapputkeep(cols, nbuf, nsiz, vbuf, vsiz); if(icv) (*env)->ReleaseByteArrayElements(env, value, vbuf, JNI_ABORT); if(icn) (*env)->ReleaseByteArrayElements(env, name, nbuf, JNI_ABORT); (*env)->DeleteLocalRef(env, value); (*env)->DeleteLocalRef(env, name); (*env)->DeleteLocalRef(env, entry); } (*env)->DeleteLocalRef(env, iter); (*env)->DeleteLocalRef(env, set); } (*env)->DeleteLocalRef(env, pkey); return flags; }
/* Synchronize updating contents on memory of a word database object. */ bool tcwdbmemsync(TCWDB *wdb, int level){ assert(wdb); if(!wdb->open || !wdb->cc){ tcbdbsetecode(wdb->idx, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bool err = false; bool (*synccb)(int, int, const char *, void *) = wdb->synccb; void *syncopq = wdb->syncopq; bool (*addcb)(const char *, void *) = wdb->addcb; void *addopq = wdb->addopq; TCBDB *idx = wdb->idx; TCMAP *cc = wdb->cc; if(synccb && !synccb(0, 0, "started", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); return false; } if(tcmaprnum(cc) > 0){ if(synccb && !synccb(0, 0, "getting tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); return false; } int kn; const char **keys = tcmapkeys2(cc, &kn); if(synccb && !synccb(kn, 0, "sorting tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); tcfree(keys); return false; } qsort(keys, kn, sizeof(*keys), (int(*)(const void *, const void *))tccmpwords); for(int i = 0; i < kn; i++){ if(synccb && !synccb(kn, i + 1, "storing tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); tcfree(keys); return false; } const char *kbuf = keys[i]; int ksiz = strlen(kbuf); int vsiz; const char *vbuf = tcmapget(cc, kbuf, ksiz, &vsiz); if(!tcbdbputcat(idx, kbuf, ksiz, vbuf, vsiz)) err = true; } if(addcb){ if(synccb && !synccb(0, 0, "storing keyword list", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); tcfree(keys); return false; } for(int i = 0; i < kn; i++){ if(!addcb(keys[i], addopq)){ tcfree(keys); return false; } } } tcfree(keys); tcmapclear(cc); } TCMAP *dtokens = wdb->dtokens; TCIDSET *dids = wdb->dids; if(tcmaprnum(dtokens) > 0){ if(synccb && !synccb(0, 0, "getting deleted tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); return false; } int kn; const char **keys = tcmapkeys2(dtokens, &kn); if(synccb && !synccb(kn, 0, "sorting deleted tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); tcfree(keys); return false; } qsort(keys, kn, sizeof(*keys), (int(*)(const void *, const void *))tccmpwords); for(int i = 0; i < kn; i++){ if(synccb && !synccb(kn, i + 1, "storing deleted tokens", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); tcfree(keys); return false; } const char *kbuf = keys[i]; int ksiz = strlen(kbuf); int vsiz; const char *vbuf = tcbdbget3(idx, kbuf, ksiz, &vsiz); if(!vbuf) continue; char *nbuf = tcmalloc(vsiz + 1); char *wp = nbuf; const char *pv; while(vsiz > 0){ pv = vbuf; int step; uint64_t id; TDREADVNUMBUF64(vbuf, id, step); vbuf += step; vsiz -= step; if(!tcidsetcheck(dids, id)){ int len = vbuf - pv; memcpy(wp, pv, len); wp += len; } } int nsiz = wp - nbuf; if(nsiz > 0){ if(!tcbdbput(idx, kbuf, ksiz, nbuf, nsiz)) err = true; } else { if(!tcbdbout(idx, kbuf, ksiz)) err = true; } tcfree(nbuf); } tcfree(keys); tcmapclear(dtokens); tcidsetclear(dids); } if(level > 0){ if(synccb && !synccb(0, 0, "synchronizing database", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); return false; } if(!tcbdbmemsync(idx, level > 1)) err = true; } if(synccb && !synccb(0, 0, "finished", syncopq)){ tcbdbsetecode(wdb->idx, TCEMISC, __FILE__, __LINE__, __func__); return false; } return !err; }