Beispiel #1
0
/*
 * Returns the size diff
 */
static int
anbtr_check_convert(ai_nbtr *anbtr, uchar pktyp)
{
	// Nothing to do
	if (anbtr->is_btree)
		return 0;

	ai_arr *arr = anbtr->u.arr;
	if (arr && (arr->used >= AI_ARR_MAX_USED)) {
		//cf_info(AS_SINDEX,"Flipped @ %d", arr->used);
		ulong ba = ai_arr_size(arr);
		// Allocate btree move digest from arr to btree
		bt *nbtr = createIndexNode(pktyp, COL_TYPE_NONE);
		if (!nbtr) {
			cf_warning(AS_SINDEX, "btree allocation failure");
			return 0;
		}

		ai_arr_move_to_tree(arr, nbtr);
		ai_arr_destroy(anbtr->u.arr);

		// Update anbtr
		anbtr->u.nbtr = nbtr;
		anbtr->is_btree = true;

		ulong aa = nbtr->msize;
		return (aa - ba);
	}
	return 0;
}
Beispiel #2
0
/*
 * Delete operation for the nbtr does the following. Delete in the arr or nbtr
 * based on state of anbtr
 *
 * Parameter:   ibtr  : Btree of key
 *              acol  : Secondary index key
 *              apk   : value (primary key to be inserted)
 *
 * Returns:
 *      AS_SINDEX_OK           : In case of success
 *      AS_SINDEX_ERR          : In case of failure
 *      AS_SINDEX_KEY_NOTFOUND : If key does not exist
 */
static int
reduced_iRem(bt *ibtr, ai_obj *acol, ai_obj *apk)
{
	ai_nbtr *anbtr = (ai_nbtr *)btIndFind(ibtr, acol);
	ulong ba = 0, aa = 0;
	if (!anbtr) {
		return AS_SINDEX_KEY_NOTFOUND;
	}
	if (anbtr->is_btree) {
		if (!anbtr->u.nbtr) return AS_SINDEX_ERR;

		// Remove from nbtr if found
		bt *nbtr = anbtr->u.nbtr;
		if (!btIndNodeExist(nbtr, apk)) {
			return AS_SINDEX_KEY_NOTFOUND;
		}
		ba = nbtr->msize;

		// TODO - Needs to be cleaner, type convert from signed
		// to unsigned. Should be 64 bit !!
		int nkeys_before = nbtr->numkeys; 
		int nkeys_after = btIndNodeDelete(nbtr, apk, NULL);
		aa = nbtr->msize;

		if (nkeys_after == nkeys_before) {
			return AS_SINDEX_KEY_NOTFOUND;
		}

		// remove from ibtr
		if (nkeys_after == 0) {
			btIndDelete(ibtr, acol);
			aa = 0;
			bt_destroy(nbtr);
			ba += sizeof(ai_nbtr);
			cf_free(anbtr);
		}
	} else {
		if (!anbtr->u.arr) return AS_SINDEX_ERR;

		// Remove from arr if found
		bool notfound = false;
		ba = ai_arr_size(anbtr->u.arr);
		anbtr->u.arr = ai_arr_delete(anbtr->u.arr, (cf_digest *)&apk->y, &notfound);
		if (notfound) return AS_SINDEX_KEY_NOTFOUND;
		aa = ai_arr_size(anbtr->u.arr);

		// Remove from ibtr
		if (anbtr->u.arr->used == 0) {
			btIndDelete(ibtr, acol);
			aa = 0;
			ai_arr_destroy(anbtr->u.arr);
			ba += sizeof(ai_nbtr);
			cf_free(anbtr);
		}
	}
	ibtr->nsize -= (ba - aa);

	return AS_SINDEX_OK;
}
Beispiel #3
0
/*
 * Delete operation for the nbtr does the following. Delete in the arr or nbtr
 * based on state of anbtr
 *
 * Parameter:   ibtr  : Btree of key
 *              acol  : Secondary index key
 *              apk   : value (primary key to be inserted)
 *
 * Returns:
 *      AS_SINDEX_OK           : In case of success
 *      AS_SINDEX_ERR          : In case of failure
 *      AS_SINDEX_KEY_NOTFOUND : If key does not exist
 */
static int
reduced_iRem(bt *ibtr, ai_obj *acol, ai_obj *apk)
{
	ai_nbtr *anbtr = (ai_nbtr *)btIndFind(ibtr, acol);
	ulong ba = 0, aa = 0;
	if (!anbtr) {
		return AS_SINDEX_ERR;
	}
	if (anbtr->is_btree) {
		if (!anbtr->u.nbtr) return AS_SINDEX_ERR;

		// Remove from nbtr if found
		bt *nbtr = anbtr->u.nbtr;
		if (!btIndNodeExist(nbtr, apk)) {
			return AS_SINDEX_KEY_NOTFOUND;
		}
		ba = nbtr->msize;
		int nkeys = btIndNodeDelete(nbtr, apk, NULL);
		aa = nbtr->msize;

		// remove from ibtr
		if (!nkeys) {
			btIndDelete(ibtr, acol);
			aa = 0;
			bt_destroy(nbtr);
			ba += sizeof(ai_nbtr);
			cf_free(anbtr);
		}
	} else {
		if (!anbtr->u.arr) return AS_SINDEX_ERR;

		// Remove from arr if found
		bool notfound = false;
		ba = ai_arr_size(anbtr->u.arr);
		anbtr->u.arr = ai_arr_delete(anbtr->u.arr, (cf_digest *)&apk->y, &notfound);
		if (notfound) return AS_SINDEX_KEY_NOTFOUND;
		aa = ai_arr_size(anbtr->u.arr);

		// Remove from ibtr
		if (anbtr->u.arr->used == 0) {
			btIndDelete(ibtr, acol);
			aa = 0;
			ai_arr_destroy(anbtr->u.arr);
			ba += sizeof(ai_nbtr);
			cf_free(anbtr);
		}
	}
	ibtr->nsize -= (ba - aa);

	return AS_SINDEX_OK;
}
Beispiel #4
0
static void
destroy_index(bt *ibtr, bt_n *n)                        
{                                                                               
	if (! n->leaf) {                                                             
		for (int i = 0; i <= n->n; i++) {                                       
			destroy_index(ibtr, NODES(ibtr, n)[i]);                     
		}                                                                       
	}                                                                           

	for (int i = 0; i < n->n; i++) {                                            
		void *be = KEYS(ibtr, n, i);                                            
		ai_nbtr *anbtr = (ai_nbtr *) parseStream(be, ibtr);                     
		if (anbtr) {                                                            
			if (anbtr->is_btree) {                                              
				bt_destroy(anbtr->u.nbtr);                                      
			} else {                                                            
				ai_arr_destroy(anbtr->u.arr);                                   
			}                                                                   
			cf_free(anbtr);                                                     
		}                                                                       
	}                                                                           
}                 
Beispiel #5
0
// Iterate through the btree and cleanup local array
// if it is btree it will be cleaned up by Aerospike Index
// call for dropIndex
static int
ai_cleanup(bt *ibtr)
{
	if (!ibtr) {
		return 0;
	}

	btSIter stack_bi;
	btEntry *be;
	btSIter *bi = btSetFullRangeIter(&stack_bi, ibtr, 1, NULL);
	if (bi) {
		while ((be = btRangeNext(bi, 1))) {
			ai_nbtr *anbtr = be->val;
			if (anbtr) {
				if (!anbtr->is_btree) {
					ai_arr_destroy(anbtr->u.arr);
				}
			}
		}
		btReleaseRangeIterator(bi);
	}

	return 0;
}