Пример #1
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;
}
Пример #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_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;
}
Пример #3
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;
}
Пример #4
0
/*
 *  return -1    in case of failure
 *          size of allocation in case of success
 */
static int
anbtr_check_init(ai_nbtr *anbtr, uchar pktyp)
{
	bool create_arr = false;
	bool create_nbtr = false;

	if (anbtr->is_btree) {
		if (anbtr->u.nbtr) {
			create_nbtr = false;
		} else {
			create_nbtr = true;
		}
	} else {
		if (anbtr->u.arr) {
			create_arr = false;
		} else {
			if (g_use_arr) {
				create_arr = true;
			} else {
				create_nbtr = true;
			}
		}
	}

	// create array or btree
	if (create_arr) {
		anbtr->u.arr = ai_arr_new();
		if (!anbtr->u.arr) {
			return -1;
		}
		return ai_arr_size(anbtr->u.arr);
	} else if (create_nbtr) {
		anbtr->u.nbtr = createIndexNode(pktyp, COL_TYPE_NONE);
		if (!anbtr->u.nbtr) {
			return -1;
		}
		anbtr->is_btree = true;
		return anbtr->u.nbtr->msize;
	} else {
		if (!anbtr->u.arr && !anbtr->u.nbtr) {
			cf_warning(AS_SINDEX, "Something wrong!!!");
			return -1;
		}
	}
	return 0;
}
Пример #5
0
/*
 *  return -1    in case of failure
 *          size of allocation in case of success
 */
static int
anbtr_check_init(ai_nbtr *anbtr, col_type_t sktype)
{
	bool create_arr = false;
	bool create_nbtr = false;

	if (anbtr->is_btree) {
		if (anbtr->u.nbtr) {
			create_nbtr = false;
		} else {
			create_nbtr = true;
		}
	} else {
		if (anbtr->u.arr) {
			create_arr = false;
		} else {
			if (g_use_arr) {
				create_arr = true;
			} else {
				create_nbtr = true;
			}
		}
	}

	// create array or btree
	if (create_arr) {
		anbtr->u.arr = ai_arr_new();
		return ai_arr_size(anbtr->u.arr);
	} else if (create_nbtr) {
		anbtr->u.nbtr = createNBT(sktype);
		if (!anbtr->u.nbtr) {
			return -1;
		}
		anbtr->is_btree = true;
		return anbtr->u.nbtr->msize;
	} else {
		if (!anbtr->u.arr && !anbtr->u.nbtr) {
			cf_warning(AS_SINDEX, "Something wrong!!!");
			return -1;
		}
	}
	return 0;
}
Пример #6
0
/*
 * Insert operation for the nbtr does the following
 * 1. Sets up anbtr if it is set up
 * 2. Inserts in the arr or nbtr depending number of elements.
 * 3. Cuts over from arr to btr at AI_ARR_MAX_USED
 *
 * Parameter:   ibtr  : Btree of key
 *              acol  : Secondary index key
 *              apk   : value (primary key to be inserted)
 *              pktyp : value type (U160 currently)
 *
 * Returns:
 *      AS_SINDEX_OK        : In case of success
 *      AS_SINDEX_ERR       : In case of failure
 *      AS_SINDEX_KEY_FOUND : If key already exists
 */
static int
reduced_iAdd(bt *ibtr, ai_obj *acol, ai_obj *apk, uchar pktyp)
{
	ai_nbtr *anbtr = (ai_nbtr *)btIndFind(ibtr, acol);
	ulong ba = 0, aa = 0;
	bool allocated_anbtr = false;
	if (!anbtr) {
		anbtr = cf_malloc(sizeof(ai_nbtr));
		aa += sizeof(ai_nbtr);
		if (!anbtr) {
			cf_warning(AS_SINDEX, "Allocation failure for anbtr");
			return AS_SINDEX_ERR;
		}
		memset(anbtr, 0, sizeof(ai_nbtr));
		allocated_anbtr = true;
	}

	// Init the array
	int ret = anbtr_check_init(anbtr, pktyp);
	if (ret < 0) {
		if (allocated_anbtr) {
			cf_free(anbtr);
		}
		return AS_SINDEX_ERR;
	} else if (ret) {
		ibtr->nsize += ret;
		btIndAdd(ibtr, acol, (bt *)anbtr);
	}

	// Convert from arr to nbtr if limit is hit
	ibtr->nsize += anbtr_check_convert(anbtr, pktyp);

	// If already a btree use it
	if (anbtr->is_btree) {
		bt *nbtr = anbtr->u.nbtr;
		if (!nbtr) {
			return AS_SINDEX_ERR;
		}

		if (btIndNodeExist(nbtr, apk)) {
			return AS_SINDEX_KEY_FOUND;
		}

		ba += nbtr->msize;
		if (!btIndNodeAdd(nbtr, apk)) {
			return AS_SINDEX_ERR;
		}
		aa += nbtr->msize;

	} else {
		ai_arr *arr = anbtr->u.arr;
		if (!arr) {
			return AS_SINDEX_ERR;
		}

		ba += ai_arr_size(anbtr->u.arr);
		bool found = false;
		ai_arr *t_arr = ai_arr_insert(arr, (cf_digest *)&apk->y, &found);
		if (!t_arr) {
			return AS_SINDEX_ERR;
		} else if (found) {
			return AS_SINDEX_KEY_FOUND;
		}
		anbtr->u.arr = t_arr;
		aa += ai_arr_size(anbtr->u.arr);
	}
	ibtr->nsize += (aa - ba);  // ibtr inherits nbtr

	return AS_SINDEX_OK;
}