std::vector<int> concurrent_attr(Graph& G, std::vector<bool>& removed, std::vector<int>& A, int i) { std::vector<int> tmpMap(G.size(), -1); std::vector<bool> check(G.size()); for (const int x : A) { tmpMap[x] = 0; check[x] = true; } int index = 0; std::vector<std::future<std::vector<int>>> results; while (index < A.size()) { while (index < A.size()) { results.push_back(std::async(async_attr, &G, &tmpMap, A[index], &removed, i)); index += 1; } for (int i = 0; i < results.size(); i++) { auto res = results[i].get(); for (auto i : res) { if (!check[i]) { check[i] = true; A.push_back(i); } } } results.clear(); } return A; }
PatchMap<1>* Cartographer::buildAdjacencyMap(const UnitType *uType, const Vec2i &pos, CardinalDir facing, Field f, int size) { PF_TRACE(); const Vec2i mapPos = pos + (OrdinalOffsets[odNorthWest] * size); const int sx = pos.x; const int sy = pos.y; Rectangle rect(mapPos.x, mapPos.y, uType->getSize() + 2 + size, uType->getSize() + 2 + size); PatchMap<1> *pMap = new PatchMap<1>(rect, 0); pMap->zeroMap(); PatchMap<1> tmpMap(rect, 0); tmpMap.zeroMap(); // mark cells occupied by unitType at pos (on tmpMap) Util::RectIterator rIter(pos, pos + Vec2i(uType->getSize() - 1)); while (rIter.more()) { Vec2i gpos = rIter.next(); if (!uType->hasCellMap() || uType->getCellMapCell(gpos.x - sx, gpos.y - sy, facing)) { tmpMap.setInfluence(gpos, 1); } } // mark goal cells on result map rIter = Util::RectIterator(mapPos, pos + Vec2i(uType->getSize())); while (rIter.more()) { Vec2i gpos = rIter.next(); if (tmpMap.getInfluence(gpos) || !masterMap->canOccupy(gpos, size, f)) { continue; // building or obstacle } Util::PerimeterIterator pIter(gpos - Vec2i(1), gpos + Vec2i(size)); while (pIter.more()) { if (tmpMap.getInfluence(pIter.next())) { pMap->setInfluence(gpos, 1); break; } } } return pMap; }
std::vector<int> attr(Graph& G, std::vector<bool>& removed, std::vector<int>& A, int i) { std::vector<int> tmpMap(G.size(), -1); for (const int x : A) { tmpMap[x] = 0; } auto index = 0; while (index < A.size()) { for (const int v0 : G.get(A[index]).get_inj()) { if (!removed[v0]) { auto flag = G.get(v0).get_player() == i; if (tmpMap[v0] == -1) { if (flag) { A.push_back(v0); tmpMap[v0] = 0; } else { int adj_counter = -1; for (const int x : G.get(v0).get_adj()) { if (!removed[x]) { adj_counter += 1; } } tmpMap[v0] = adj_counter; if (adj_counter == 0) { A.push_back(v0); } } } else if (!flag and tmpMap[v0] > 0) { tmpMap[v0] -= 1; if (tmpMap[v0] == 0) { A.push_back(v0); } } } } index += 1; } return A; }
RddResultCode TopNAction::action(ActionContext* ctx, const BaseRddPartition* input) { TopNActionRequest request; if (!ctx->getActionParam(ACTION_PARAM, &request)) { LOG(ERROR)<< input->getPartitionName() << " parse top N expression error"; return RRC_INVALID_ACTION_PARAM; } int32_t fieldSize = request.order_field_size(); vector<FieldInfo> fields; vector<bool> fieldDesc; fields.resize(fieldSize); fieldDesc.resize(fieldSize); string typeName = input->getRddName(); for (int32_t i = 0; i < fieldSize; ++ i) { auto& field = request.order_field(i); auto rc = ExpressionFactory::build(&fields[i].expr, field.expr(), ctx->getKeyTemplate(), ctx->getValueTemplate()); if (idgs::RC_SUCCESS != rc) { LOG(ERROR)<< input->getPartitionName() << " parsed filter expression error, caused by " << idgs::getErrorDescription(rc); return RRC_NOT_SUPPORT; } if (field.has_field_name()) { fields[i].name = field.field_name(); } else if (field.expr().name() == "FIELD") { fields[i].name = field.expr().value(); } else { fields[i].name = "column" + to_string(i); } if (field.has_field_type()) { fields[i].type = field.field_type(); } else if (field.expr().name() == "FIELD") { FieldExtractor* fieldExt = dynamic_cast<FieldExtractor*>(fields[i].expr); auto fldType = fieldExt->getFieldType(); fields[i].type = static_cast<idgs::pb::DataType>(fldType); } else { fields[i].type = idgs::pb::STRING; } fieldDesc[i] = field.desc(); typeName.append("_").append(fields[i].name); } string fullTypeName = "idgs.rdd.pb." + typeName; auto helper = idgs_rdd_module()->getMessageHelper(); if (!helper->isMessageRegistered(fullTypeName)) { std::lock_guard<std::mutex> lockGuard(lock); if (!helper->isMessageRegistered(fullTypeName)) { registerTempKeyMessage(input->getPartition(), typeName, fields); } } if (input->empty()) { return RRC_SUCCESS; } PbMessagePtr tmpKeyTemp = helper->createMessage(fullTypeName); if (!tmpKeyTemp) { LOG(ERROR)<< "RDD \"" << input->getRddName() << "\" partition[" << input->getPartition() << "] generate dynamic key error."; return RRC_INVALID_KEY; } orderless compare(fieldDesc); multimap<PbMessagePtr, KeyValueMessagePair, orderless> tmpMap(compare); auto tmpDescriptor = tmpKeyTemp->GetDescriptor(); uint64_t start = 1, dataSize = 0; bool hasTop = request.has_top_n(); if (request.has_start()) { start = request.start(); } if (request.has_top_n()) { auto topN = request.top_n(); dataSize = topN + start - 1; } input->foreach( [&ctx, &tmpMap, fields, tmpKeyTemp, tmpDescriptor, dataSize, hasTop, helper] (const PbMessagePtr& key, const PbMessagePtr& value) { ctx->setKeyValue(&key, &value); if (!ctx->evaluateFilterExpr()) { return; } PbMessagePtr tmpKey(tmpKeyTemp->New()); for (int32_t i = 0; i < tmpDescriptor->field_count(); ++ i) { auto field = tmpDescriptor->field(i); PbVariant var = fields[i].expr->evaluate(ctx->getExpressionContext()); helper->setMessageValue(tmpKey.get(), field, var); } KeyValueMessagePair pair; pair.key = &key; pair.value = &value; tmpMap.insert(std::pair<PbMessagePtr, KeyValueMessagePair>(tmpKey, pair)); if (hasTop && tmpMap.size() > dataSize) { auto itTmp = tmpMap.end(); -- itTmp; tmpMap.erase(itTmp); } }); if (!tmpMap.empty()) { TopNActionData data; data.set_key_name(fullTypeName); auto serdesMode = ctx->getSerdesMode(); auto itfst = tmpMap.begin(); auto itlst = tmpMap.end(); for (; itfst != itlst; ++ itfst) { auto pair = data.add_data(); ProtoSerdesHelper::serialize(serdesMode, itfst->first.get(), pair->mutable_key()); ProtoSerdesHelper::serialize(serdesMode, itfst->second.key->get(), pair->mutable_pair()->mutable_key()); ProtoSerdesHelper::serialize(serdesMode, itfst->second.value->get(), pair->mutable_pair()->mutable_value()); } string var; ProtoSerdesHelper::serialize(serdesMode, &data, &var); ctx->addPartitionResult(var); } return RRC_SUCCESS; }
RddResultCode TopNAction::aggregate(ActionContext* ctx) { TopNActionRequest request; if (!ctx->getActionParam(ACTION_PARAM, &request)) { return RRC_INVALID_ACTION_PARAM; } int32_t fieldSize = request.order_field_size(); vector<bool> fieldDesc; fieldDesc.resize(fieldSize); for (int32_t i = 0; i < fieldSize; ++ i) { auto& field = request.order_field(i); fieldDesc[i] = field.desc(); } uint64_t start = (request.has_start()) ? request.start() : 1; bool hasTop = request.has_top_n(); uint64_t dataSize = (hasTop) ? request.top_n() + start - 1 : 0; orderless compare(fieldDesc); multimap<PbMessagePtr, KeyValuePair, orderless> tmpMap(compare); auto helper = idgs_rdd_module()->getMessageHelper(); TopNActionData data; auto& input = ctx->getAggregateResult(); auto it = input.begin(); auto serdesMode = ctx->getSerdesMode(); for (; it != input.end(); ++ it) { if (!it->empty()) { ProtoSerdesHelper::deserialize(serdesMode, (*it)[0], &data); for (int32_t i = 0; i < data.data_size(); ++i) { auto tmpKey = helper->createMessage(data.key_name()); auto pair = data.data(i); ProtoSerdesHelper::deserialize(serdesMode, pair.key(), tmpKey.get()); KeyValuePair kvPair = pair.pair(); tmpMap.insert(std::pair<PbMessagePtr, KeyValuePair>(tmpKey, kvPair)); if (hasTop && tmpMap.size() > dataSize) { auto itTmp = tmpMap.end(); -- itTmp; tmpMap.erase(itTmp); } } } } shared_ptr<TopNActionResult> result = make_shared<TopNActionResult>(); if (!tmpMap.empty()) { auto itfst = tmpMap.begin(); auto itlst = tmpMap.end(); uint64_t index = 1; for (; itfst != itlst; ++ itfst, ++ index) { if (index >= start) { result->add_pair()->CopyFrom(itfst->second); } } } ctx->setActionResult(result); return RRC_SUCCESS; }