int ol_scoop(ol_database *db, const char *key, size_t klen) { if (db->is_enabled(OL_F_DISABLE_TX, &db->feature_set) || db->state == OL_S_COMMITTING || db->state == OL_S_STARTUP) { /* Fake a transaction: */ ol_transaction stack_tx = { .tx_id = 0, .parent_db = NULL, .transaction_db = db }; return olt_scoop(&stack_tx, key, klen); } ol_transaction *tx = olt_begin(db); int scoop_ret = OL_SUCCESS; check(tx != NULL, "Could not begin implicit transaction."); scoop_ret = olt_scoop(tx, key, klen); check(scoop_ret == OL_SUCCESS, "Could not scoop value. Aborting."); check(olt_commit(tx) == OL_SUCCESS, "Could not commit transaction."); return OL_SUCCESS; error: if (tx != NULL && scoop_ret != 10) olt_abort(tx); return OL_FAILURE; }
int olt_unjar(ol_transaction *tx, const char *key, size_t klen, unsigned char **data, size_t *dsize) { char _key[KEY_SIZE] = {'\0'}; size_t _klen = 0; ol_database *operating_db = NULL; ol_bucket *bucket = ol_get_bucket(tx->transaction_db, key, klen, &_key, &_klen); check(_klen > 0, "Key length of zero not allowed."); /* Fall through to the parent db: */ if (bucket == NULL) { bucket = ol_get_bucket(tx->parent_db, key, klen, &_key, &_klen); /* This is getting messy... */ if (bucket != NULL) operating_db = tx->parent_db; } else { operating_db = tx->transaction_db; } if (bucket != NULL) { if (!_has_bucket_expired(bucket)) { /* We don't need to fill out the data so just return 'we found the key'. */ if (data == NULL) return OL_SUCCESS; const int ret = _ol_get_value_from_bucket(operating_db, bucket, data, dsize); check(ret == 0, "Could not retrieve value from bucket."); /* Key found, tell somebody. */ return OL_SUCCESS; } else { /* It's dead, get rid of it. */ /* NOTE: We explicitly say the transaction_db here because ITS A * F*****G TRANSACTION. ACID, bro. */ check(olt_scoop(tx, key, klen) == 0, "Scoop failed"); } } /* TODO: Set error code here (could not find key) */ return OL_FAILURE; error: /* TODO: Set error code here (generic error? Theres a couple failure modes here.)*/ return OL_FAILURE; }