/* * This file is part of rasdaman community. * * Rasdaman community is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rasdaman community is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ #include "tiler.hh" #include "tilemgr/tile.hh" r_Tiler::r_Tiler(std::vector& sourceDomain2s, const std::vector& targetDomain2s) : sourceDomains(sourceDomain2s), targetDomains(targetDomain2s) { } void r_Tiler::mergeDomains() { std::vector::iterator splitedIt; std::vector temp; r_Minterval tempDom; bool merged = false; while (!splitedDomains.empty()) { merged = false; tempDom = *(splitedDomains.begin()); splitedDomains.erase(splitedDomains.begin()); for (splitedIt = splitedDomains.begin(); splitedDomains.end() != splitedIt; splitedIt++) { if (tempDom.is_mergeable(*splitedIt)) { //cout << "is mergeable " << tempDom << " " << *splitedIt << endl; tempDom.closure_with(*splitedIt); //cout << "closure " << tempDom << endl; splitedDomains.erase(splitedIt); merged = true; break; } else { //cout << "is not mergeable " << tempDom << " " << *splitedIt << endl; } } if (merged) splitedDomains.push_back(tempDom); else temp.push_back(tempDom); } splitedDomains = temp; } void r_Tiler::split() { std::vector::iterator sourceIt; std::vector::iterator retvalIt; std::vector splits; std::vector points; for (sourceIt = sourceDomains.begin(); sourceIt != sourceDomains.end(); sourceIt++) { //cout << "starting with source domain " << *sourceIt << endl; points = computeSplitDimensions(*sourceIt); splits = splitMinterval(*sourceIt, points); for (retvalIt = splits.begin(); retvalIt != splits.end(); retvalIt++) { splitedDomains.push_back(*retvalIt); } //it is either splitted and in retval or not splitted and then there is an error, because not splitted were inserted } } std::vector r_Tiler::computeSplitDimensions(const r_Minterval& sourceDomain) const { r_Dimension dim = 0; r_Range slow = 0; r_Range shigh = 0; r_Range ilow = 0; r_Range ihigh = 0; std::vector intersects; std::vector::iterator intersectIt; std::vector::const_iterator targetIt; std::vector points; std::vector::iterator pointIt; RangePair pair; //cout << "\tfinding the intersections of current source with targets" << endl; for (targetIt = targetDomains.begin(); targetIt != targetDomains.end(); targetIt++) { if ((*targetIt).intersects_with(sourceDomain)) { //cout << "\t\tsource intersected target " << *targetIt << endl; intersects.push_back((*targetIt).create_intersection(sourceDomain)); } else { //cout << "\t\tsource did not intersect target " << *targetIt << endl; } } //cout << "\titerating through intersecting domains to determine the spliting dimensions" << endl; for (intersectIt = intersects.begin(); intersectIt != intersects.end(); intersectIt++) { //cout << "\t\tstarting to compute split dimensions with " << *intersectIt << endl; for (dim = 0; dim < (*intersectIt).dimension(); dim++) { ilow = (*intersectIt)[dim].low(); ihigh = (*intersectIt)[dim].high(); slow = (sourceDomain)[dim].low(); shigh = (sourceDomain)[dim].high(); //cout << "\t\t\tdimension " << dim << endl; //cout << "\t\t\tsource low " << (sourceDomain)[dim].low() << "=" << slow << ", intersect low " << (*intersectIt)[dim].low() << "=" << ilow << endl; //cout << "\t\t\tsource high " << (sourceDomain)[dim].high() << "=" << shigh << ", intersect high " << (*intersectIt)[dim].high() << "=" << ihigh << endl; if ((slow <= ilow) & (shigh >= ilow)) { pair.first = dim; pair.second = ilow - 1; //cout << "\t\t\tadding " << pair.second << endl; points.push_back(pair); } if ((slow <= ihigh) & (shigh >= ihigh)) { pair.first = dim; pair.second = ihigh; //cout << "\t\t\tadding " << pair.second << endl; points.push_back(pair); } } //cout << "\t\tfound all split dimensions for the current source with intersect " << *intersectIt << endl; } //cout << "\t\t\tfound all split dimensions for source " << sourceDomain << endl; //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; //cout << "try " << endl; std::vector temp; std::vector::iterator tempIt; RangePair tempP; bool tempadd = true; temp.swap(points); //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; //cout << "try end" << endl; while (!temp.empty()) { tempadd = true; tempP = *(temp.begin()); temp.erase(temp.begin()); for (tempIt = temp.begin(); tempIt != temp.end(); tempIt++) { if ((tempP.first == (*tempIt).first) & (tempP.second == (*tempIt).second)) { //cout << "matched" << endl; tempadd = false; break; } } if (tempadd) points.push_back(tempP); } //cout << "try end 2" << endl; //for (pointIt = points.begin(); pointIt != points.end(); pointIt++) //cout << "\t\t\tsplit in dimension " << (*pointIt).first << " at coordinate " << (*pointIt).second << endl; //cout << "try end 3" << endl; return points; } std::vector r_Tiler::splitMinterval(const r_Minterval& sourceTile, std::vector& points) { std::vector splits; std::vector split2s; std::vector::iterator splitIt; std::vector::iterator split2It; r_Minterval splitInterval1; r_Minterval splitInterval2; std::vector::iterator pointIt; bool addDomain = false; r_Dimension dim = 0; r_Range low = 0; r_Range high = 0; r_Range splitCoordinate = 0; //initialize the split std::vector. the result will contain a list of splitted domains. splits.push_back(sourceTile); //cout << "\t\tstarting to actually split" << endl; for (pointIt = points.begin(); pointIt != points.end(); pointIt++) { split2s = std::vector(); //cout << "\t\t\tstarting to split at dimension " << (*pointIt).first << " coordinate " << (*pointIt).second << endl; //cout << "\t\t\titerating through all the tiles to be split, stemming from current source tile" << endl; while (!splits.empty()) { splitIt = splits.begin(); //cout << "\t\t\t\tsplitting " << (*splitIt) << endl; addDomain = false; splitInterval1 = r_Minterval(((*splitIt)).dimension()); splitInterval2 = r_Minterval(((*splitIt)).dimension()); //cout << "\t\t\t\ttrying split" << endl; for (dim = 0; dim < ((*splitIt)).dimension(); dim++) { if ((dim == (*pointIt).first)) { high = (*splitIt)[dim].high(); low = (*splitIt)[dim].low(); splitCoordinate = (*pointIt).second; if ((splitCoordinate < high) & (splitCoordinate > low)) { //cout << "\t\t\t\t\tsplit middle adding [" << low << ":" << splitCoordinate << "]" << endl; splitInterval1 << r_Sinterval(low, splitCoordinate); //cout << "\t\t\t\t\tsplit middle adding [" << splitCoordinate+1 << ":" << high << "]" << endl; splitInterval2 << r_Sinterval(splitCoordinate + 1, high); addDomain = true; } else { if (splitCoordinate == high) { addDomain = true; if (low == high) { //cout << "\t\t\t\t\tsplit high adding [" << low << ":" << low << "]" << endl; splitInterval1 << r_Sinterval(low, high); } else { //cout << "\t\t\t\t\tsplit high adding [" << low << ":" << high-1<<"]" << endl; splitInterval1 << r_Sinterval(low, splitCoordinate - 1); } splitInterval2 << r_Sinterval(splitCoordinate, splitCoordinate); } else { if ((*pointIt).second == ((*splitIt))[dim].low()) { addDomain = true; if (low == high) { //cout<<"\t\t\t\t\tsplit low adding ["< retval; bool kill = false; std::vector::iterator targetIt; retval.swap(splitedDomains); while (!retval.empty()) { temp = *(retval.begin()); retval.erase(retval.begin()); kill = false; for (targetIt = retval.begin(); targetIt != retval.end(); targetIt++) { if ((*targetIt).intersects_with(temp)) { kill = true; break; } } if (!kill) splitedDomains.push_back(temp); } } void r_Tiler::removeDoubleDomains() { r_Minterval temp; std::vector retval; bool kill = false; std::vector::iterator targetIt; while (!splitedDomains.empty()) { temp = *(splitedDomains.begin()); splitedDomains.erase(splitedDomains.begin()); kill = false; for (targetIt = targetDomains.begin(); targetIt != targetDomains.end(); targetIt++) { if ((*targetIt).intersects_with(temp)) { kill = true; break; } } if (!kill) retval.push_back(temp); } retval.swap(splitedDomains); } std::vector r_Tiler::getTiledDomains() const { return splitedDomains; } std::vector r_Tiler::generateTiles(const std::vector& sourceTiles) const { std::vector::const_iterator splitedDomIt; std::vector::const_iterator sourceTileIt; std::vector retval; r_Minterval dummy; Tile* p = 0; const BaseType* basetype = (*sourceTiles.begin())->getType(); r_Data_Format dataformat = (*sourceTiles.begin())->getDataFormat(); for (splitedDomIt = splitedDomains.begin(); splitedDomIt != splitedDomains.end(); splitedDomIt++) { dummy = *splitedDomIt; p = new Tile(dummy, basetype, dataformat); //std::cout << "new tile " << dummy << " " << basetype->getName() << " " << dataformat << " size " << p->getSize() << " other size " << p->getDBTile()->getSize() << std::endl; for (sourceTileIt = sourceTiles.begin(); sourceTileIt != sourceTiles.end(); sourceTileIt++) { //std::cout << " the other tile domain " << (*sourceTileIt)->getDomain() << " type " << (*sourceTileIt)->getType()->getName() << std::endl; if (dummy.intersects_with((*sourceTileIt)->getDomain())) { const r_Minterval& updateDomain = dummy.create_intersection((*sourceTileIt)->getDomain()); //std::cout << " they intersect. on " << updateDomain << std::endl; //UnaryOp* tempOp = Ops::getUnaryOp(Ops::OP_IDENTITY, p->getType(), (*sourceTileIt)->getType(), 0, 0); //causes fmr/abr/umr p->copyTile(updateDomain, *sourceTileIt, updateDomain); //p->execUnaryOp(tempOp, dummy.create_intersection((*sourceTileIt)->getDomain()), *sourceTileIt, dummy.create_intersection((*sourceTileIt)->getDomain())); //delete tempOp; } } retval.push_back(p); } return retval; }