/** ******************************************************************************* * \brief ******************************************************************************/ static void kv_async_dispatch(async_CB_t *pCB) { uint32_t new_flags = pCB->flags; new_flags &= ~KV_ASYNC_CB_QUEUED; new_flags |= KV_ASYNC_CB_RUNNING; pCB->flags = new_flags; if (pCB->flags & KV_ASYNC_CB_SET) { KV_TRC_IO(pFT, "DISPATCH: SET: %p", pCB); kv_async_SET_KEY(pCB); } else if (pCB->flags & KV_ASYNC_CB_GET) { KV_TRC_IO(pFT, "DISPATCH: GET: %p", pCB); kv_async_GET_KEY(pCB); } else if (pCB->flags & KV_ASYNC_CB_EXISTS) { KV_TRC_IO(pFT, "DISPATCH: EXI: %p", pCB); kv_async_EXISTS_KEY(pCB); } else if (pCB->flags & KV_ASYNC_CB_DEL) { KV_TRC_IO(pFT, "DISPATCH: DEL: %p", pCB); kv_async_DEL_KEY(pCB); } else { EXPECT_TRUE(0); } }
/** ******************************************************************************* * \brief * callback function for set/get/exists/del ******************************************************************************/ static void kv_async_cb(int errcode, uint64_t dt, int64_t res) { async_CB_t *pCB = (async_CB_t*)dt; kv_t *p_kv = NULL; uint64_t tag = (uint64_t)pCB; if (pCB == NULL) { KV_TRC_FFDC(pFT, "FFDC: pCB NULL"); return; } if (pCB->b_mark != B_MARK) { KV_TRC_FFDC(pFT, "FFDC: B_MARK FAILURE %p: %"PRIx64"", pCB, pCB->b_mark); return; } if (pCB->e_mark != E_MARK) { KV_TRC_FFDC(pFT, "FFDC: E_MARK FAILURE %p: %"PRIx64"", pCB, pCB->e_mark); return; } if (EBUSY == errcode) {kv_async_q_retry(pCB); goto done;} if (IS_GTEST) { EXPECT_EQ(0, errcode); EXPECT_EQ(tag, pCB->tag); } p_kv = pCB->db + pCB->len_i; ++pCB->len_i; if (pCB->flags & KV_ASYNC_CB_SET) { KV_TRC_IO(pFT, "KV_ASYNC_CB_SET, %p %d %d", pCB, pCB->len_i, pCB->len); if (0 != errcode) printf("ark_set failed, errcode=%d\n", errcode); if (tag != pCB->tag) printf("ark_set bad tag\n"); if (res != p_kv->vlen) printf("ark_set bad vlen\n"); if (IS_GTEST) { EXPECT_EQ(res, p_kv->vlen);} /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { if (pCB->flags & KV_ASYNC_CB_WRITE_PERF) { pCB->len_i = 0; kv_async_perf_done(pCB); goto done; } pCB->len_i = 0; pCB->flags &= ~KV_ASYNC_CB_SET; pCB->flags |= KV_ASYNC_CB_GET; kv_async_GET_KEY(pCB); goto done; } kv_async_SET_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_CB_GET) { uint32_t miscompare = memcmp(p_kv->value, pCB->gvalue, p_kv->vlen); KV_TRC_IO(pFT, "KV_ASYNC_CB_GET, %p %d %d", pCB, pCB->len_i, pCB->len); if (0 != errcode) printf("ark_get failed, errcode=%d\n", errcode); if (tag != pCB->tag) printf("ark_get bad tag\n"); if (res != p_kv->vlen) printf("ark_get bad vlen\n"); if (IS_GTEST) { EXPECT_EQ(0, miscompare);} /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { if (pCB->flags & KV_ASYNC_CB_READ_PERF) { pCB->len_i = 0; kv_async_perf_done(pCB); goto done; } pCB->len_i = 0; pCB->flags &= ~KV_ASYNC_CB_GET; pCB->flags |= KV_ASYNC_CB_EXISTS; kv_async_EXISTS_KEY(pCB); goto done; } kv_async_GET_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_CB_EXISTS) { KV_TRC_IO(pFT, "KV_ASYNC_CB_EXISTS, %p %d %d", pCB, pCB->len_i, pCB->len); if (0 != errcode) printf("ark_exists failed,errcode=%d\n",errcode); if (tag != pCB->tag) printf("ark_exists bad tag\n"); if (res != p_kv->vlen) printf("ark_exists bad vlen\n"); if (IS_GTEST) { EXPECT_EQ(res, p_kv->vlen);} /* if end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { pCB->len_i = 0; pCB->flags &= ~KV_ASYNC_CB_EXISTS; if (pCB->flags & KV_ASYNC_CB_SGD) { pCB->flags |= KV_ASYNC_CB_DEL; kv_async_DEL_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_CB_REPLACE) { /* make sure we don't shutdown before we have replaced once */ if (pCB->replace && pCB->flags & KV_ASYNC_CB_SHUTDOWN) { pCB->flags |= KV_ASYNC_CB_DEL; kv_async_DEL_KEY(pCB); goto done; } pCB->replace = TRUE; if (0 != pCB->regen(pCB->db, pCB->len, pCB->regen_len)) { printf("regen failure, fatal\n"); KV_TRC_FFDC(pFT, "FFDC: regen failure"); memset(pCB, 0, sizeof(async_CB_t)); goto done; } pCB->flags |= KV_ASYNC_CB_SET; kv_async_SET_KEY(pCB); goto done; } else { /* should not be here */ EXPECT_TRUE(0); } } kv_async_EXISTS_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_CB_DEL) { KV_TRC_IO(pFT, "KV_ASYNC_CB_DEL, %p i:%d len:%d", pCB, pCB->len_i,pCB->len); if (0 != errcode) printf("ark_del failed, errcode=%d\n",errcode); if (tag != pCB->tag) printf("ark_del bad tag\n"); if (res != p_kv->vlen) printf("ark_del bad vlen\n"); if (IS_GTEST) { EXPECT_EQ(res, p_kv->vlen);} /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { if (pCB->flags & KV_ASYNC_CB_SHUTDOWN) { if (!(pCB->flags & KV_ASYNC_CB_MULTI_CTXT_IO)) { kv_db_destroy(pCB->db, pCB->len); } if (pCB->gvalue) free(pCB->gvalue); memset(pCB, 0, sizeof(async_CB_t)); KV_TRC_IO(pFT, "LOOP_DONE: %p", pCB); goto done; } KV_TRC_IO(pFT, "NEXT_LOOP, %p", pCB); pCB->flags &= ~KV_ASYNC_CB_DEL; pCB->flags |= KV_ASYNC_CB_SET; pCB->len_i = 0; kv_async_SET_KEY(pCB); goto done; } kv_async_DEL_KEY(pCB); goto done; } else { /* should not be here */ EXPECT_TRUE(0); } done: return; }
/** ******************************************************************************** ** \brief ** callback for ark functions: set,get,exists,del *******************************************************************************/ void kv_async_cb(int errcode, uint64_t dt, int64_t res) { async_context_t *pCT = pCTs+GET_CTXT(dt); async_CB_t *pCB = NULL; kv_t *p_kv = NULL; if (NULL == pCT) KV_ERR_STOP(pCB, "bad dt: ctxt", 0); pCB = pCT->pCBs+GET_CB(dt); if (NULL == pCB) KV_ERR_STOP(pCB, "bad dt: cb", 0); if (0 != errcode) KV_ERR_STOP(pCB, "bad errcode", errcode); if (dt != pCB->tag) KV_ERR_STOP(pCB, "bad tag", 0); if (res != pCB->db->vlen) KV_ERR_STOP(pCB, "bad res", 0); p_kv = pCB->db->kv + pCB->len_i; ++pCB->len_i; if (pCB->flags & KV_ASYNC_SET) { /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { pCB->len_i = 0; pCB->flags &= ~KV_ASYNC_SET; pCB->flags |= KV_ASYNC_GET; kv_async_GET_KEY(pCB); goto done; } kv_async_SET_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_GET) { if (0 != memcmp(p_kv->value, pCB->gvalue, pCB->db->vlen)) { KV_ERR_STOP(pCB,"get miscompare",0); } /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { pCB->len_i = 0; if (read100 && !(pCB->flags & KV_ASYNC_SHUTDOWN)) { kv_async_GET_KEY(pCB); } else { pCB->flags &= ~KV_ASYNC_GET; pCB->flags |= KV_ASYNC_EXISTS; kv_async_EXISTS_KEY(pCB); } goto done; } kv_async_GET_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_EXISTS) { /* if end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { pCB->len_i = 0; pCB->flags &= ~KV_ASYNC_EXISTS; pCB->flags |= KV_ASYNC_DEL; kv_async_DEL_KEY(pCB); goto done; } kv_async_EXISTS_KEY(pCB); goto done; } else if (pCB->flags & KV_ASYNC_DEL) { /* end of db len sequence, move to next step */ if (pCB->len_i == pCB->len) { if (pCB->flags & KV_ASYNC_SHUTDOWN) { pCB->flags &= ~KV_ASYNC_RUNNING; goto done; } pCB->flags &= ~KV_ASYNC_DEL; pCB->flags |= KV_ASYNC_SET; pCB->len_i = 0; kv_async_SET_KEY(pCB); goto done; } kv_async_DEL_KEY(pCB); goto done; } else { /* should not be here */ assert(0); } done: return; }