/* * 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; }
/* * 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, ¬found); 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; }
/* * 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, ¬found); 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; }
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); } } }
// 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; }