Status Resolver::resolveRelativePathsStartingAddresses( const vector<Address>& relativePathAddresses, Mask& mask, vector<BrowsePath>& results, vector<Status>& statuses) { // declare the return status Status ret(statuscodes::Good); // declare the number of relative paths size_t noOfRelativePaths = relativePathAddresses.size(); // resize the output parameters results.resize(noOfRelativePaths); statuses.resize(noOfRelativePaths); // fill a vector containing all starting addresses vector<Address> startingAddresses; for (size_t i = 0; i < noOfRelativePaths && ret.isGood(); i++) { if (mask.isSet(i)) startingAddresses.push_back(*(relativePathAddresses[i].getStartingAddress())); } // resolve them (recursively!) vector<ExpandedNodeId> startingAddressesResults; vector<Status> startingAddressesStatuses; ret = resolve(startingAddresses, startingAddressesResults, startingAddressesStatuses); // update the results for (size_t i = 0, j = 0; i < noOfRelativePaths && ret.isGood(); i++) { if (mask.isSet(i)) { // update the results results[i].startingExpandedNodeId = startingAddressesResults[j]; results[i].relativePath = relativePathAddresses[i].getRelativePath(); // update the statuses statuses[i] = startingAddressesStatuses[j]; // update the mask (only resolved starting addresses should be processed further!) if (statuses[i].isNotGood()) mask.unset(i); // increment the index of the startingAddressesResults j++; } } return ret; }
/** * Add Exchange in GridBuffer memory space. * * An Exchange is added to this GridBuffer. The exchange buffers use * the same memory as this GridBuffer. * * @param dataPlace place where received data are stored [GUARD | BORDER] * if dataPlace=GUARD than copy other BORDER to my GUARD * if dataPlace=BORDER than copy other GUARD to my BORDER * @param receive a Mask which describes the directions for the exchange * @param guardingCells number of guarding cells in each dimension * @param sizeOnDevice if true, internal buffers have their size information on the device, too */ void addExchange(uint32_t dataPlace, const Mask &receive, DataSpace<DIM> guardingCells, uint32_t communicationTag, bool sizeOnDevice = false) { if (hasOneExchange && (communicationTag != lastUsedCommunicationTag)) throw std::runtime_error("It is not allowed to give the same GridBuffer different communicationTags"); lastUsedCommunicationTag = communicationTag; receiveMask = receiveMask + receive; sendMask = this->receiveMask.getMirroredMask(); Mask send = receive.getMirroredMask(); for (uint32_t ex = 1; ex< -12 * (int) DIM + 6 * (int) DIM * (int) DIM + 9; ++ex) { if (send.isSet(ex)) { uint32_t uniqCommunicationTag = (communicationTag << 5) | ex; if (!hasOneExchange && !privateGridBuffer::UniquTag::getInstance().isTagUniqu(uniqCommunicationTag)) { std::stringstream message; message << "unique exchange communication tag (" << uniqCommunicationTag << ") witch is created from communicationTag (" << communicationTag << ") allready used for other gridbuffer exchange"; throw std::runtime_error(message.str()); } hasOneExchange = true; if (sendExchanges[ex] != NULL) { throw std::runtime_error("Exchange already added!"); } //std::cout<<"Add Exchange: send="<<ex<<" receive="<<Mask::getMirroredExchangeType((ExchangeType)ex)<<std::endl; maxExchange = std::max(maxExchange, ex + 1u); sendExchanges[ex] = new ExchangeIntern<BORDERTYPE, DIM > (*deviceBuffer, gridLayout, guardingCells, (ExchangeType) ex, uniqCommunicationTag, dataPlace == GUARD ? BORDER : GUARD, sizeOnDevice); ExchangeType recvex = Mask::getMirroredExchangeType(ex); maxExchange = std::max(maxExchange, recvex + 1u); receiveExchanges[recvex] = new ExchangeIntern<BORDERTYPE, DIM > ( *deviceBuffer, gridLayout, guardingCells, recvex, uniqCommunicationTag, dataPlace == GUARD ? GUARD : BORDER, sizeOnDevice); } } }
/** * Add Exchange in dedicated memory space. * * An Exchange is added to this GridBuffer. The exchange buffers use * the their own memory instead of using the GridBuffer's memory space. * * @param receive a Mask which describes the directions for the exchange * @param dataSpace size of the newly created exchange buffer in each dimension * @param sizeOnDevice if true, internal buffers have their size information on the device, too */ void addExchangeBuffer(const Mask &receive, const DataSpace<DIM> &dataSpace, uint32_t communicationTag, bool sizeOnDevice = false) { if (hasOneExchange && (communicationTag != lastUsedCommunicationTag)) throw std::runtime_error("It is not allowed to give the same GridBuffer different communicationTags"); lastUsedCommunicationTag = communicationTag; /*don't create buffer with 0 (zero) elements*/ if (dataSpace.productOfComponents() != 0) { receiveMask = receiveMask + receive; sendMask = this->receiveMask.getMirroredMask(); Mask send = receive.getMirroredMask(); for (uint32_t ex = 1; ex < 27; ++ex) { if (send.isSet(ex)) { uint32_t uniqCommunicationTag = (communicationTag << 5) | ex; if (!hasOneExchange && !privateGridBuffer::UniquTag::getInstance().isTagUniqu(uniqCommunicationTag)) { std::stringstream message; message << "unique exchange communication tag (" << uniqCommunicationTag << ") witch is created from communicationTag (" << communicationTag << ") allready used for other gridbuffer exchange"; throw std::runtime_error(message.str()); } hasOneExchange = true; if (sendExchanges[ex] != NULL) { throw std::runtime_error("Exchange already added!"); } //GridLayout<DIM> memoryLayout(size); maxExchange = std::max(maxExchange, ex + 1u); sendExchanges[ex] = new ExchangeIntern<BORDERTYPE, DIM > (/*memoryLayout*/ dataSpace, ex, uniqCommunicationTag, sizeOnDevice); ExchangeType recvex = Mask::getMirroredExchangeType(ex); maxExchange = std::max(maxExchange, recvex + 1u); receiveExchanges[recvex] = new ExchangeIntern<BORDERTYPE, DIM > (/*memoryLayout*/ dataSpace, recvex, uniqCommunicationTag, sizeOnDevice); } } } }
Status Resolver::verifyExpandedNodeIds( const vector<Address>& addresses, const Mask& mask, vector<ExpandedNodeId>& results, vector<Status>& resultStatuses) { logger_->debug("Now verifying %d ExpandedNodeIds", addresses.size()); Status ret(statuscodes::Good); // verify the 'set' targets for (size_t i = 0; i < addresses.size() && ret.isGood(); i++) { if (mask.isSet(i)) { // copy the ExpandedNodeId results[i] = addresses[i].getExpandedNodeId(); // set the status if (results[i].hasServerUri()) { if ( results[i].nodeId().hasNameSpaceIndex() \ || results[i].nodeId().hasNameSpaceUri()) { database_->addressCache.add(addresses[i], results[i]); resultStatuses[i] = statuscodes::Good; } else { ret = NoNamespaceIndexOrUriGivenError(); } } else { ret = EmptyServerUriError(); } } } return ret; }
Status Resolver::resolveRelativePaths( const vector<Address>& addresses, const Mask& mask, vector<ExpandedNodeId>& results, vector<Status>& statuses) { // declare the return status Status ret; // declare a vector of browse paths which we will try to translate into ExpandedNodeIds vector<BrowsePath> browsePaths; // declare a mask that will indicate which browse paths still need to be translated Mask remainingMask = mask; // first try to resolve the starting addresses (all at once!) // the 'remainingMask', 'browsePaths' and 'statuses' will be updated! ret = resolveRelativePathsStartingAddresses( addresses, remainingMask, browsePaths, statuses); // now try to resolve the relative paths (essentially browse paths since their starting // addresses have been resolved) if (ret.isGood()) ret = resolveBrowsePaths(browsePaths, remainingMask, results, statuses); // add the resolved addresses to the cache for (size_t i = 0; i < addresses.size() && ret.isGood(); i++) { if (mask.isSet(i) && statuses[i].isGood()) { database_->addressCache.add(addresses[i], results[i], true); } } return ret; }
// Resolve a relative path (which may span over multiple server address spaces!) //============================================================================================== Status Resolver::resolveBrowsePaths( vector<BrowsePath>& browsePaths, Mask& mask, vector<ExpandedNodeId>& results, vector<Status>& statuses) { logger_->debug("Resolving %d browse paths", browsePaths.size()); // declare the return status Status ret; // declare the number of browsePaths size_t noOfBrowsePaths = browsePaths.size(); // resize the output arguments results.resize(noOfBrowsePaths); statuses.resize(noOfBrowsePaths); // check if the mask has the correct size if (mask.size() != noOfBrowsePaths) { ret = UnexpectedError("Mask does not have the correct size!"); } else if (mask.setCount() == 0) { logger_->debug("Nothing to do, no browse paths are marked with the mask"); } else { // create a request and a result TranslateBrowsePathsToNodeIdsRequest request; TranslateBrowsePathsToNodeIdsResult result; for (size_t i = 0; i < noOfBrowsePaths; i++) { if (mask.isSet(i)) request.targets.push_back( TranslateBrowsePathsToNodeIdsRequestTarget(browsePaths[i])); } ret = sessionFactory_->invokeRequest<TranslateBrowsePathsToNodeIdsService>( request, Mask(request.targets.size(), true), result); if (ret.isGood()) { // fill the remainingBrowsePaths and remainingMask for (size_t i = 0, j = 0; i < noOfBrowsePaths; i++) { if (mask.isSet(i)) { processBrowsePathsResolutionResultTarget( result.targets[j], i, browsePaths, mask, results, statuses); // increment the counter for the 'set' results j++; } } // check if we need to perform another (recursive!) translation if (mask.setCount() > 0) ret = resolveBrowsePaths(browsePaths, mask, results, statuses); } } return ret; }