void Controller::storeInto(Key& key, shared_ptr<Value> value, const Choice& choice, const Requirements& requirements) { Actor* actor = choice.getActor(); Dbg() << "chose " << choice.desc() << " for this" << endl; if (requirements.metadata.empty()) { actor->put(key, value, choice.getProfile()); } else { actor->put(key, value, choice.getProfile(), &requirements.metadata); } }
void Controller::checkMigration(Key& key, const Choice& current, bool extraGet, shared_ptr<Value> valueGot) { Requirements requirements; size_t size; { lock_guard<mutex> guard(infoLock); if (info.count(key) == 0) return; requirements = *info[key].requirements.get(); size = info[key].size; } Condition condition = prepareCondition(key, size, requirements); double estimatedCost; Choice* choice = decider->findBetter(condition, current, extraGet, &estimatedCost); if (choice != nullptr) { Dbg() << "migrating from " << current.desc() << " to " << choice->desc() << endl; shared_ptr<Value> value; Requirements migrateRequirements; if (extraGet) { value = current.getActor()->get(key, current.getProfile()); } else { value = valueGot; } storeInto(key, value, *choice, requirements); choice_id old_id = memory->remember(key, choice->getId()); deleteFrom(key, current); accountant->recordMigrate(current.getId(), choice->getId(), size, extraGet); } }
shared_ptr<Value> Controller::handleGet(Key& key, const Requirements& requirements) { shared_ptr<Value> value; Requirements mutable_requirements = requirements; choice_id cid; if (memory->recall(key, &cid)) { auto cit = choices.find(cid); assert(cit != choices.end()); Choice choice = cit->second; accountant->recordGet(cid); Actor* actor = choice.getActor(); Dbg() << "choice " << choice.desc() << "handle this" << endl; if (requirements.prefer_url) { value = actor->get_url(key, requirements.expiration, choice.getProfile()); } if (!value) { value = actor->get(key, choice.getProfile(), requirements.range, &mutable_requirements.metadata); } if (!value) { Err() << "cannot find " << key.toString() << " in choice " << choice.desc() << endl; for (auto& choice_pair : choices) { Choice& choice = choice_pair.second; if (choice.getActor()->get(key, choice.getProfile(), requirements.range, &mutable_requirements.metadata)) { Err() << "found key in " << choice.desc() << "instead" << endl; abort(); } } } if (enableGetMigration) { bool extraGet = !value->hasUrl(); checkMigration(key, choice, extraGet, value); } } estimator->notifyGet(key, mutable_requirements); if (enableStat) { stat->notifyGet(key); } return value; }
void Controller::deleteFrom(Key& key, const Choice& choice) { Actor* actor = choice.getActor(); actor->del(key, choice.getProfile()); }