void PosUpdateScan::executePlanOperation() { auto c_pc = checked_pointer_cast<const storage::PointerCalculator>(input.getTable(0)); auto c_store = checked_pointer_cast<const storage::Store>(c_pc->getActualTable()); // Cast the constness away auto store = std::const_pointer_cast<storage::Store>(c_store); // Get the offset for inserts into the delta and the size of the delta that // we need to increase by the positions we are inserting auto writeArea = store->appendToDelta(c_pc->getPositions()->size()); const size_t firstPosition = store->getMainTable()->size() + writeArea.first; // Get the modification record for the current transaction auto& txmgr = tx::TransactionManager::getInstance(); auto& modRecord = txmgr[_txContext.tid]; // Functor we use for updating the data set_json_value_functor fun(store->getDeltaTable()); storage::type_switch<hyrise_basic_types> ts; size_t counter = 0; for (const auto& p : *(c_pc->getPositions())) { // First delete the old record bool deleteOk = store->markForDeletion(p, _txContext.tid) == tx::TX_CODE::TX_OK; if (!deleteOk) { txmgr.rollbackTransaction(_txContext); throw tx::transaction_error("Aborted TX because TID of other TX found (Op: PosUpdateScan, Table: " + store->getName() + ")"); } modRecord.deletePos(store, p); // store->setTid(p, _txContext.tid); // Copy the old row from the main store->copyRowToDelta(store, p, writeArea.first + counter, _txContext.tid); // Update all the necessary values for (const auto& kv : _raw_data) { const auto& fld = store->numberOfColumn(kv.first); fun.set(fld, writeArea.first + counter, kv.second); ts(store->typeOfColumn(fld), fun); } // Update delta indices store->addRowToDeltaIndices(firstPosition + counter); // Insert the new one modRecord.insertPos(store, firstPosition + counter); #ifdef PERSISTENCY_BUFFEREDLOGGER std::vector<ValueId> vids = store->copyValueIds(firstPosition + counter); if (store->loggingEnabled()) { io::Logger::getInstance().logValue(_txContext.tid, store->getName(), firstPosition + counter, &vids); io::Logger::getInstance().logInvalidation(_txContext.tid, store->getName(), p); } #endif ++counter; } // Update affected rows auto rsp = getResponseTask(); if (rsp != nullptr) rsp->incAffectedRows(counter); addResult(c_store); }
std::list<MGPathItem> MGMap::calculatePath(eMGFPathType pathType, int ax, int ay, int bx, int by) { // Algorithm MGFSKYPATH: // 1) Step (x,y) towards target. Diagonally first and then straight ahead. // Algorithm MGFBASICPATH1: // 1) For all non-blocked adjacent tiles of (x,y) not already in the path, calculate estimated distance to target. // 2) Push the "best" alternative to the path. Back-track if necessary. // 3) Step (x,y) and goto 1) MGFLOG_INFO("MGMap::calculatePath will find a path (" << ax << ", " << ay << ") -> (" << bx << ", " << by << ")"); std::list<MGPathItem> path; if(pathType == MGFASTARLIST) { MGPathGenerator::calculatePathAStar(ax, ay, bx, by, *this, path); } else if(pathType == MGFBASICPATH1) { MGPathGenerator::calculatePathBasic(ax, ay, bx, by, *this, path); } else if(pathType == MGFSKYPATH) { int x = ax; int y = ay; while (x != bx || y != by) { if(x > bx && y > by) { x--; y--; } else if(x < bx && y < by) { x++; y++; } else if(x > bx && y < by) { x--; y++; } else if(x < bx && y > by) { x++; y--; } else if(x < bx) { x++; } else if(x > bx) { x--; } else if(y < by) { y++; } else //if(y > by) { y--; } MGPathItem *pI = new MGPathItem(x, y); path.push_back(*pI); //TODO: Call constructor without new as argument. }//while } // XXX: Perhaps come up with a better way to print the path? if(!path.empty()) { if(loggingEnabled()) { MGFLOG_INFO("Path:"); for (std::list<MGPathItem>::iterator it = path.begin(); it != path.end(); ++it) { MGFLOG_INFO("(" << it->getX() << ", " << it->getY() << ")"); } } } else { // XXX: What is this caused by? It actually happens sometimes. MGFLOG_WARNING("MGMap::calculatePath produced an empty path"); } return path; }