diff --git a/ermia.cc b/ermia.cc index 3ffd06e2..a536aef1 100644 --- a/ermia.cc +++ b/ermia.cc @@ -199,6 +199,54 @@ void ConcurrentMasstreeIndex::GetRecord(transaction *t, rc_t &rc, const varstr & } } +void ConcurrentMasstreeIndex::GetRecordMulti(transaction *t, rc_t &rc, const varstr &key, + std::vector &result_vec, std::vector *out_oid) { + rc = {RC_INVALID}; + OID dir_oid = INVALID_OID; + std::vector oids; + ermia::varstr tmpval; + if (!t) { + auto e = MM::epoch_enter(); + rc._val = masstree_.search(key, dir_oid, e, nullptr) ? RC_TRUE : RC_FALSE; + MM::epoch_exit(0, e); + } else { + t->ensure_active(); + bool found = masstree_.search(key, dir_oid, t->xc->begin_epoch, nullptr); + dbtuple *tuple = nullptr; + if (found) { + LOG_IF(FATAL, config::is_backup_srv()) << "GetRecordMulti is not supportted for backup server"; + bool ok = oidmgr->oid_get_dir(table_descriptor->GetTupleArray(), dir_oid, oids); + ALWAYS_ASSERT(ok); + for (auto &o : oids) { + tuple = oidmgr->oid_get_version(table_descriptor->GetTupleArray(), o, t->xc); + if (!tuple) { + DLOG(WARNING) << "(SKIPPED) Some tuple is empty: OID = " << std::hex << o; + found = false; + } + + if (found) { + bool ret = t->DoTupleRead(tuple, &tmpval)._val; + if (!ret) { + DLOG(WARNING) << "(SKIPPED) Cannot do tuple read for OID = " << std::hex << o; + continue; + } + result_vec.push_back(tmpval); + } else if (config::phantom_prot) { + // volatile_write(rc._val, DoNodeRead(t, sinfo.first, sinfo.second)._val); + } else { + continue; + } + } + volatile_write(rc._val, RC_TRUE); + return; + } else { + volatile_write(rc._val, RC_FALSE); + return; + } + } +} + + void ConcurrentMasstreeIndex::PurgeTreeWalker::on_node_begin( const typename ConcurrentMasstree::node_opaque_t *n) { ASSERT(spec_values.empty()); diff --git a/ermia.h b/ermia.h index a97a36e0..ac7195bf 100644 --- a/ermia.h +++ b/ermia.h @@ -146,6 +146,8 @@ class ConcurrentMasstreeIndex : public OrderedIndex { virtual void GetRecord(transaction *t, rc_t &rc, const varstr &key, varstr &value, OID *out_oid = nullptr) override; + virtual void GetRecordMulti(transaction *t, rc_t &rc, const varstr &key, std::vector &value, + std::vector *oids = nullptr); rc_t UpdateRecord(transaction *t, const varstr &key, varstr &value) override; rc_t InsertRecord(transaction *t, const varstr &key, varstr &value, OID *out_oid = nullptr) override;