/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }