예제 #1
0
int
ai_findandset_imatch(as_sindex_metadata *imd, as_sindex_pmetadata *pimd, int idx)
{
	if (!Num_tbls) {
		return AS_SINDEX_ERR;
	}

	char *tname = NULL, *cname = NULL, *iname = NULL;
	int ret = AS_SINDEX_OK;

	if (!(tname = create_tname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	ret = AS_SINDEX_ERR;

	AI_GRLOCK();

	int tmatch = find_table(tname);
	if (tmatch == -1) {
		goto END;
	}
	if (imd->iname) {
		if (!(iname = get_iname_from_imd(imd))) {
			ret = AS_SINDEX_ERR_NO_MEMORY;
			goto END;
		}
		char idx_str[NAME_STR_LEN];
		snprintf(idx_str, sizeof(idx_str), "%d", idx);
		char *piname = str_concat(iname, '.', idx_str);
		pimd->imatch = match_partial_index_name(piname);
		cf_free(piname);
	} else {
		if (!(cname = create_cname_from_imd(imd))) {
			ret = AS_SINDEX_ERR_NO_MEMORY;
			goto END;
		}
		icol_t *ic = find_column(tmatch, cname);
		if (!ic) {
			goto END;
		}
		pimd->imatch = find_partial_index(tmatch, ic);
	}
	if (pimd->imatch == -1) {
		SITRACE(imd->si, META, debug, "Index%s: %s not found", imd->iname ? "" : "column-name", imd->iname ? iname : cname);
		goto END;
	}

	ret = AS_SINDEX_OK;

END:

	AI_UNLOCK();

	cf_free(tname);
	cf_free(iname);
	cf_free(cname);

	return ret;
}
예제 #2
0
int
ai_btree_destroy(as_sindex_metadata *imd)
{
	char *tname, *cname, *iname;

	AI_GWLOCK();

	for (int i = 0; i < imd->nprts; i++) {
		ai_cleanup(imd->pimd[i].ibtr);
	}

	if (!(tname = create_tname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	if (!(cname = create_cname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	if (0 > ai_drop_column(tname, cname)) {
		cf_warning(AS_SINDEX, "Failed to drop column %s from table %s", cname, tname);
	}

	cf_free(tname);
	cf_free(cname);

	if (!(iname = get_iname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	if (0 > ai_drop_index(iname)) {
		cf_warning(AS_SINDEX, "Failed to drop index %s", iname);
	}

	cf_free(iname);

	AI_UNLOCK();

	return AS_SINDEX_OK;
}
예제 #3
0
/* NOTE: The creation of a secondary index is the following two commands
          0.) optional: CREATE TABLE namespace (pk U160, __dummy TEXT)
          1.) ALTER TABLE namespace ADD COLUMN binname columntype
          2.) CREATE [UNIQUE] INDEX indexname ON namespace (binname)
 */
int
ai_btree_create(as_sindex_metadata *imd, int simatch, int *bimatch, int nprts)
{
	char *iname = NULL, *cname = NULL, *tname = NULL;
	int ret = AS_SINDEX_ERR, rv;

	if (1 != imd->num_bins) {
		cf_warning(AS_SINDEX, "Multi-bin indexes not supported");
		return ret;
	}

	if (!(tname = create_tname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	if (!(cname = create_cname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	AI_GWLOCK();

	int tmatch = find_table(tname);
	if (tmatch == -1) {
		if (0 > (rv = ai_create_table(tname))) {
			cf_warning(AS_SINDEX, "Create table %s failed (rv %d)", tname, rv);
			goto END;
		}
		tmatch = find_table(tname);
	}
	r_tbl_t *rt = &Tbl[tmatch];

	// 1.) add entries in Aerospike Index's virtual TABLE
	int col_type = imd->btype[0];
	icol_t *ic = find_column(tmatch, cname);
	if (!ic) { // COLUMN does not exist
		if (0 > ai_add_column(tname, cname, col_type)) {
			goto END;
		}
		// Add (cmatch+1) always non-zero
		SITRACE(imd->si, META, debug, "Added Mapping [BINNAME=%s: BINID=%d: COLID%d] [IMATCH=%d: SIMATCH=%d: INAME=%s]",
				imd->bnames[0], imd->binid[0], rt->col_count, Num_indx - 1, simatch, imd->iname);
	}

	//NOTE: COMMAND: CREATE PARTITIONED INDEX iname ON tname (cname) NUM = nprts
	if (!(iname = get_iname_from_imd(imd))) {
		ret = AS_SINDEX_ERR_NO_MEMORY;
		goto END;
	}

	if (0 > (rv = ai_create_index(iname, tname, cname, col_type, nprts))) {
		cf_warning(AS_SINDEX, "Create index %s failed (rv %d)", iname, rv);
		goto END;
	}

	*bimatch = match_partial_index_name(iname);
	GTRACE(META, debug, "cr8SecIndex: iname: %s bname: %s type: %d ns: %s set: %s tmatch: %d bimatch: %d",
		   imd->iname, imd->bnames[0], imd->btype[0], imd->ns_name, imd->set, tmatch, *bimatch);

	ret = AS_SINDEX_OK;

END:

	AI_UNLOCK();

	cf_free(tname);
	cf_free(cname);
	cf_free(iname);

	return ret;
}
예제 #4
0
/*
 * Aerospike Index interface to build a defrag_list.
 *
 * Returns :
 *  AS_SINDEX_DONE     ---> The current pimd has been scanned completely for defragging
 *  AS_SINDEX_CONTINUE ---> Current pimd sill may have some candidate digest to be defragged
 *  AS_SINDEX_ERR      ---> Error. Abort this pimd.
 *
 *  Notes :  Caller has the responsibility to free the iterators.
 *           Requires a proper offset value from the caller.
 */
int
ai_btree_build_defrag_list(as_sindex_metadata *imd, as_sindex_pmetadata *pimd, ai_obj *icol,
						   long *nofst, long limit, uint64_t * tot_processed, uint64_t * tot_found, cf_ll *gc_list)
{
	int ret = AS_SINDEX_ERR;

	if (!pimd || !imd) {
		return ret;
	}

	as_namespace *ns = imd->si->ns;
	if (!ns) {
		ns = as_namespace_get_byname((char *)imd->ns_name);
	}
	char *iname = get_iname_from_imd(imd);
	if (!iname) {
		ret = AS_SINDEX_ERR_NO_MEMORY;
		return ret;
	}
	if (!pimd || !pimd->ibtr || !pimd->ibtr->numkeys) {
		goto END;
	}
	//Entry is range query, FROM previous icol TO maxKey(ibtr)
	if (icol->empty) {
		assignMinKey(pimd->ibtr, icol); // init first call
	}
	ai_obj iH;
	assignMaxKey(pimd->ibtr, &iH);
	btEntry *be = NULL;
	btSIter *bi = btGetRangeIter(pimd->ibtr, icol, &iH, 1);
	if (!bi) {
		goto END;
	}

	while ( true ) {
		be = btRangeNext(bi, 1);
		if (!be) {
			ret = AS_SINDEX_DONE;
			break;
		}
		ai_obj *acol = be->key;
		ai_nbtr *anbtr = be->val;
		long processed = 0;
		if (!anbtr) {
			break;
		}
		if (anbtr->is_btree) {
			processed = build_defrag_list_from_nbtr(ns, acol, anbtr->u.nbtr, *nofst, &limit, tot_found, gc_list);
		} else {
			processed = build_defrag_list_from_arr(ns, acol, anbtr->u.arr, *nofst, &limit, tot_found, gc_list);
		}

		if (processed < 0) {    // error .. abort everything.
			cf_detail(AS_SINDEX, "build_defrag_list returns an error. Aborting defrag on current pimd");
			ret = AS_SINDEX_ERR;
			break;
		}
		*tot_processed += processed;
		// This tree may have some more digest to defrag
		if (limit == 0) {
			*nofst = *nofst + processed;
			ai_objClone(icol, acol);
			cf_detail(AS_SINDEX, "Current pimd may need more iteration of defragging.");
			ret = AS_SINDEX_CONTINUE;
			break;
		}

		// We have finished this tree. Yet we have not reached our limit to defrag.
		// Goes to next iteration
		*nofst = 0;
		ai_objClone(icol, acol);
	};
	btReleaseRangeIterator(bi);
END:
	cf_free(iname);

	return ret;
}
예제 #5
0
int
ai_findandset_imatch(as_sindex_metadata *imd, as_sindex_pmetadata *pimd, int idx)
{
	if (!Num_tbls) {
		return AS_SINDEX_ERR;
	}

	char *tname = NULL;
	char *cname = NULL;
	char *iname = NULL;

	if (!(tname = create_tname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	int ret = AS_SINDEX_ERR;

	AI_GRLOCK();

	int tmatch = find_table(tname);
	if (tmatch == -1) {
		goto END;
	}
	if (imd->iname) {
		// This is always true
		if (!(iname = get_iname_from_imd(imd))) {
			ret = AS_SINDEX_ERR_NO_MEMORY;
			goto END;
		}
		
		char piname[INDD_HASH_KEY_SIZE];
		snprintf(piname, sizeof(piname), "%s.%d", iname, idx);	
		pimd->imatch = match_partial_index_name(piname);
	} else {
		// CAUTION : This will not work. Since ci->list is only populated for 0th pimd
		if (!(cname = create_cname_from_imd(imd))) {
			ret = AS_SINDEX_ERR_NO_MEMORY;
			goto END;
		}
		icol_t *ic = find_column(tmatch, cname);
		if (!ic) {
			goto END;
		}
		pimd->imatch = find_partial_index(tmatch, ic);
		cf_free(ic);
	}
	if (pimd->imatch == -1) {
		cf_debug(AS_SINDEX, "Index %s not found for %dth pimd", imd->iname, idx);
		goto END;
	}

	ret = AS_SINDEX_OK;

END:

	AI_UNLOCK();

	if (tname) {
		cf_free(tname);
	}
	if (iname) { 
		cf_free(iname);
	}
	if (cname) {
		cf_free(cname);
	}
	return ret;
}
예제 #6
0
/* NOTE: The creation of a secondary index is the following two commands
          0.) optional: CREATE TABLE namespace (pk U160, __dummy TEXT)
          1.) ALTER TABLE namespace ADD COLUMN binname columntype
          2.) CREATE [UNIQUE] INDEX indexname ON namespace (binname)
 */
int
ai_btree_create(as_sindex_metadata *imd, int simatch, int *bimatch, int nprts)
{
	char *iname = NULL, *cname = NULL, *tname = NULL;
	int ret = AS_SINDEX_ERR, rv;

	if (!(tname = create_tname_from_imd(imd))) {
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	if (!(cname = create_cname_from_imd(imd))) {
		if (tname) {
			cf_free(tname);
		}
		return AS_SINDEX_ERR_NO_MEMORY;
	}

	AI_GWLOCK();

	// TODO : ai_create_table has this check. So this is redundant
	// 3 shash_get can be reduced to 1 through ai_get_or_create_table func
	int tmatch = find_table(tname);
	if (tmatch == -1) {
		if (0 > (rv = ai_create_table(tname))) {
			cf_warning(AS_SINDEX, "Create table %s failed (rv %d)", tname, rv);
			goto END;
		}
		tmatch = find_table(tname);
	}
	r_tbl_t *rt = &Tbl[tmatch];

	// 1.) add entries in Aerospike Index's virtual TABLE
	int col_type = imd->btype;
	icol_t *ic = find_column(tmatch, cname);
	if (!ic) { // COLUMN does not exist
		if (0 > ai_add_column(tname, cname, col_type)) {
			goto END;
		}
		// Add (cmatch+1) always non-zero
		cf_debug(AS_SINDEX, "Added Mapping [BINNAME=%s: BINID=%d: COLID%d] [IMATCH=%d: SIMATCH=%d: INAME=%s]",
				imd->bname, imd->binid, rt->col_count, Num_indx - 1, simatch, imd->iname);
	}
	else {
		cf_free(ic);
	}

	//NOTE: COMMAND: CREATE PARTITIONED INDEX iname ON tname (cname) NUM = nprts
	if (!(iname = get_iname_from_imd(imd))) {
		ret = AS_SINDEX_ERR_NO_MEMORY;
		goto END;
	}

	if (0 > (rv = ai_create_index(iname, tname, cname, col_type, nprts))) {
		cf_warning(AS_SINDEX, "Create index %s failed (rv %d)", iname, rv);
		goto END;
	}

	*bimatch = match_partial_index_name(iname);
	cf_debug(AS_SINDEX, "cr8SecIndex: iname: %s bname: %s type: %d ns: %s set: %s tmatch: %d bimatch: %d",
		   imd->iname, imd->bname, imd->btype, imd->ns_name, imd->set, tmatch, *bimatch);

	ret = AS_SINDEX_OK;

END:

	AI_UNLOCK();

	if (tname) {
		cf_free(tname);
	}
	if (cname) {
		cf_free(cname);
	}
	if (iname) {
		cf_free(iname);
	}
	return ret;
}