/*
* 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 .
/
/**
* SOURCE: tiling.cc
*
* MODULE: rasodmg
* CLASS: r_Tiling
*
* COMMENTS:
* None
*
*/
//for max min
#include
//for pow
#include
#include
#include "rasodmg/tiling.hh"
#include "raslib/rmdebug.hh"
#include "raslib/minterval.hh"
#include "rasodmg/gmarray.hh"
#include "raslib/dlist.hh"
const char*
r_Tiling::ASTERIX = "*";
const char*
r_Tiling::TCOLON = ";";
const char*
r_Tiling::TCOMMA = ",";
const char*
r_Tiling::LSQRBRA = "[";
const char*
r_Tiling::RSQRBRA = "]";
const long
r_Tiling::DefaultBase = 10;
r_Tiling::~r_Tiling()
{
}
const char*
r_No_Tiling::description = "no parameters";
r_No_Tiling::r_No_Tiling(const char* encoded) throw(r_Error)
{
//we don't use encoded string, it is present in order to have
//uniform interface "char* constructor" for every tiling strategy
}
r_No_Tiling::r_No_Tiling()
{
}
r_No_Tiling::~r_No_Tiling()
{
}
void
r_No_Tiling::print_status(std::ostream& os) const
{
os << "r_No_Tiling[ ]";
}
bool
r_No_Tiling::is_compatible(const r_Minterval& obj_domain, r_Bytes cellTypeSize) const
{
return true;
}
std::vector*
r_No_Tiling::compute_tiles(const r_Minterval& obj_domain, r_Bytes cellTypeSize) const throw (r_Error)
{
RMDBGENTER(4, RMDebug::module_rasodmg, "r_No_Tiling", "compute_tiles(" << obj_domain << ", " << cellTypeSize << ")")
std::vector* result = new std::vector;
result->push_back(obj_domain);
RMDBGEXIT(4, RMDebug::module_rasodmg, "r_No_Tiling", "compute_tiles() " << *result)
return result;
}
r_Tiling*
r_No_Tiling::clone() const
{
r_Tiling* clo = new r_No_Tiling();
return clo;
}
r_Tiling_Scheme
r_No_Tiling::get_tiling_scheme() const
{
return r_NoTiling;
}
std::ostream&
operator<<(std::ostream& os, const r_Tiling& t)
{
t.print_status(os);
return os;
}
const char*
r_Size_Tiling::description = "tile configuration or tile dimension and tile size (in bytes) (ex: \"[0:9,0:9];100\" or \"2;100\")";
r_Size_Tiling::r_Size_Tiling(const char* encoded) throw (r_Error)
: tile_size(0)
{
if(!encoded) {
RMInit::logOut << "r_Size_Tiling::r_Size_Tiling(" << (encoded?encoded:"NULL") << ")" << endl;
throw r_Error(TILINGPARAMETERNOTCORRECT);
}
r_Bytes tileS=strtol(encoded, (char**)NULL, DefaultBase);
if(tileS<=0) {
RMInit::logOut << "r_Size_Tiling::r_Size_Tiling(" << encoded << "): Error decoding tile size." << endl;
throw r_Error(TILINGPARAMETERNOTCORRECT);
}
tile_size = tileS;
}
r_Size_Tiling::r_Size_Tiling(r_Bytes ts) :
tile_size(ts)
{
}
r_Size_Tiling::~r_Size_Tiling()
{
}
r_Bytes
r_Size_Tiling::get_tile_size() const
{
return tile_size;
}
void
r_Size_Tiling::print_status(std::ostream& os) const
{
os << "r_Size_Tiling[ tile size = " << tile_size << " ]";
}
bool
r_Size_Tiling::is_compatible(const r_Minterval& obj_domain, r_Bytes cellTypeSize) const
{
return ((cellTypeSize <= tile_size) && (obj_domain.dimension() != 0));
}
std::vector*
r_Size_Tiling::compute_tiles(const r_Minterval& obj_domain, r_Bytes cellTypeSize) const throw (r_Error)
{
RMDBGENTER(4, RMDebug::module_rasodmg, "r_Size_Tiling", "compute_tiles(" << obj_domain << ", " << cellTypeSize << ")")
if (cellTypeSize > tile_size)
{
RMInit::logOut << "r_Size_Tiling::compute_tiles(" << obj_domain << ", " << cellTypeSize << ") tile size (" << tile_size << ") is smaller than type length (" << cellTypeSize << ")" << endl;
throw r_Error(TILESIZETOOSMALL);
}
std::vector* result = new std::vector;
r_Minterval bigDom = obj_domain;
r_Dimension dim = bigDom.dimension();
r_Minterval tileDom(dim);
// compute the domain of the small tiles
// tiles are n-dimensional cubes with edge length n-th root of max tile size
RMDBGMIDDLE(4, RMDebug::module_rasodmg, "r_Size_Tiling", "tile size " << get_tile_size())
r_Range edgeLength = (r_Range)std::max((r_Range)floor(pow(get_tile_size()/cellTypeSize, 1/(double)dim)), 1);
r_Dimension dimcnt = 0;
for (dimcnt = 0; dimcnt < dim; dimcnt++)
tileDom << r_Sinterval((r_Range)0, edgeLength - 1);
r_Minterval currDom(dim);
r_Point cursor(dim);
r_Point tileSize;
r_Point origin;
bool done = 0;
// initialize cursor
for (dimcnt = 0; dimcnt < dim; dimcnt++)
cursor[dimcnt] = 0;
// calculate size of Tiles
tileSize = tileDom.get_extent();
// origin of bigTile
origin = bigDom.get_origin();
// initialize currDom
for (dimcnt=0; dimcnt < dim; dimcnt++)
currDom << r_Sinterval((r_Range)origin[dimcnt], (r_Range)(origin[dimcnt] + tileSize[dimcnt] - 1));
// resets tileDom to lower left side of bigTile
tileDom = currDom;
// intersect with bigTile
currDom.intersection_with(bigDom);
// iterate with smallTile over bigTile
while (!done)
{
currDom.intersection_with(bigDom);
// create new smallTile
r_Minterval smallTile(dim);
smallTile = currDom;
// insert tile in set
result->push_back(smallTile);
// increment cursor, start with highest dimension
r_Dimension i = cursor.dimension() - 1;
cursor[i] += tileSize[i];
// move cursor
currDom = tileDom.create_translation(cursor);
while (!(currDom.intersects_with( bigDom )))
{
cursor[i] = 0;
if (i == 0)
{
done = true;
break;
}
i--;
cursor[i] += tileSize[i];
// move cursor
currDom = tileDom.create_translation(cursor);
}
}
RMDBGEXIT(4, RMDebug::module_rasodmg, "r_Size_Tiling", "compute_tiles() " << *result)
return result;
}
r_Tiling*
r_Size_Tiling::clone() const
{
r_Tiling* clo = new r_Size_Tiling(tile_size);
return clo;
}
r_Tiling_Scheme
r_Size_Tiling::get_tiling_scheme() const
{
return r_SizeTiling;
}
/*
std::ostream&
operator<<(std::ostream& os, const r_Size_Tiling& t)
{
t.print_status(os);
return os;
}
*/
r_Dimension_Tiling::r_Dimension_Tiling(r_Dimension dim, r_Bytes ts)
: r_Size_Tiling(ts),
dimension(dim)
{
}
r_Dimension_Tiling::~r_Dimension_Tiling()
{
}
r_Dimension
r_Dimension_Tiling::get_dimension() const
{
return dimension;
}
void
r_Dimension_Tiling::print_status(std::ostream& os) const
{
os << "r_Dimension_Tiling[ ";
r_Size_Tiling::print_status(os);
os << " dimension = " << dimension << " ]";
}
bool
r_Dimension_Tiling::is_compatible(const r_Minterval& obj_domain, r_Bytes cellTypeSize) const
{
return ((obj_domain.dimension() == dimension) && r_Size_Tiling::is_compatible(obj_domain, cellTypeSize));
}
/*
std::ostream&
operator<<(std::ostream& os, const r_Dimension_Tiling& t)
{
t.print_status(os);
return os;
}
*/