/* if return item is not NULL, free by caller */ item *item_get(char *key, size_t nkey){ item *it = NULL; DBT dbkey, dbdata; bool stop; int ret; /* first, alloc a fixed size */ it = item_alloc2(settings.item_buf_size); if (it == 0) { return NULL; } BDB_CLEANUP_DBT(); dbkey.data = key; dbkey.size = nkey; dbdata.ulen = settings.item_buf_size; dbdata.data = it; dbdata.flags = DB_DBT_USERMEM; stop = false; /* try to get a item from bdb */ while (!stop) { switch (ret = dbp->get(dbp, NULL, &dbkey, &dbdata, 0)) { case DB_BUFFER_SMALL: /* user mem small */ /* free the original smaller buffer */ item_free(it); /* alloc the correct size */ it = item_alloc2(dbdata.size); if (it == NULL) { return NULL; } dbdata.ulen = dbdata.size; dbdata.data = it; break; case 0: /* Success. */ stop = true; break; case DB_NOTFOUND: stop = true; item_free(it); it = NULL; break; default: /* TODO: may cause bug here, if return DB_BUFFER_SMALL then retun non-zero again * here 'it' may not a full one. a item buffer larger than item_buf_size may be added to freelist */ stop = true; item_free(it); it = NULL; if (settings.verbose > 1) { fprintf(stderr, "dbp->get: %s\n", db_strerror(ret)); } } } return it; }
/* if return item is not NULL, free by caller */ item *bdb_get(char *key){ pthread_rwlock_rdlock(&qlist_ht_lock); item *it = NULL; DB_TXN *txnp = NULL; int ret; queue_t *q = (queue_t *)hashtable_search(qlist_htp, (void *)key); /* queue not exsited */ if (q == NULL) { pthread_rwlock_unlock(&qlist_ht_lock); return NULL; } else { DBT dbkey, dbdata; db_recno_t recno; /* first, alloc a fixed size */ it = item_alloc2(); if (it == 0) { pthread_rwlock_unlock(&qlist_ht_lock); return NULL; } BDB_CLEANUP_DBT(); dbkey.data = &recno; dbkey.ulen = sizeof(recno); dbkey.flags = DB_DBT_USERMEM; dbdata.ulen = bdb_settings.re_len; dbdata.data = it; dbdata.flags = DB_DBT_USERMEM; ret = envp->txn_begin(envp, NULL, &txnp, 0); CHECK_DB_RET(ret); ret = q->dbp->get(q->dbp, txnp, &dbkey, &dbdata, DB_CONSUME); CHECK_DB_RET(ret); ret = txnp->commit(txnp, 0); CHECK_DB_RET(ret); pthread_mutex_lock(&(q->lock)); (q->get_hits)++; pthread_mutex_unlock(&(q->lock)); } pthread_rwlock_unlock(&qlist_ht_lock); return it; dberr: item_free(it); it = NULL; if (txnp != NULL){ txnp->abort(txnp); } if (settings.verbose > 1) { fprintf(stderr, "bdb_get: %s\n", db_strerror(ret)); } pthread_rwlock_unlock(&qlist_ht_lock); return NULL; }