/* * Return 0 in case of success * -1 in case of failure */ static int get_recl(as_sindex_metadata *imd, ai_obj *afk, as_sindex_qctx *qctx) { as_sindex_pmetadata *pimd = &imd->pimd[qctx->pimd_idx]; ai_nbtr *anbtr = (ai_nbtr *)btIndFind(pimd->ibtr, afk); if (!anbtr) { return 0; } if (anbtr->is_btree) { if (add_recs_from_nbtr(imd, NULL, anbtr->u.nbtr, qctx, qctx->new_ibtr)) { return -1; } } else { // If already entire batch is returned if (qctx->nbtr_done) { return 0; } if (add_recs_from_arr(imd, NULL, anbtr->u.arr, qctx)) { return -1; } } 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; }
/* * 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; }