/*
* 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 .
*/
/*************************************************************
*
*
* PURPOSE:
* Tile is the abstract base class for persTile, transTile
* and constTile
*
*
* COMMENTS:
*
************************************************************/
#ifndef _TILE_HH_
#define _TILE_HH_
#include
#include
#include "raslib/minterval.hh" // for r_Minterval
#include "raslib/point.hh" // for r_Point
#include "raslib/mddtypes.hh" // for r_Data_Format
#include "catalogmgr/ops.hh" // for Ops::OpType
#include "relcatalogif/basetype.hh" // for BaseType
#include "relblobif/tileid.hh"
#include "relblobif/dbtile.hh"
#include "reladminif/dbref.hh"
#ifdef RMANBENCHMARK
#include "raslib/rmdebug.hh" // for RMTimer
#endif
class KeyObject;
class PersMDDObjIx;
class r_Tile_Compression;
//@ManMemo: Module: {\bf cachetamgr}.
/*@Doc:
Tile can be compressed with different algorithms which are implemented as subclasses of \Ref{Compression}. For uncompressed tiles, the special
subclass NoCompression is used.
{\bf Interdependencies}
Tile uses a pointer to \Ref{BaseType} to store the base type of the Tile.
It uses a \Ref{r_Minterval} to store the domain of the Tile.
Pointers to Tiles are used by many classes.
Compression is done in subclasses of \Ref{Compression}.
Persistent Tiles are created either by servercomm, when data is received from a client, or by indexif if a BLOBTile is retrieved from the
index. The query tree can also create tiles in case of INSERT or UPDATE queries, and Tile::splitTile creates new tiles.
*/
/**
* \defgroup Tilemgrs Tilemgr Classes
*/
/**
* \ingroup Tilemgrs
*/
class Tile
{
public:
/// assignment operator (needed, as class uses dynamic memory).
const Tile& operator=(const Tile& cell);
Tile(const r_Minterval& newDom, const BaseType* newType, DBTileId newBLOBTile);
/*Doc
Constructs a new Tile with basetype {\tt newType} and spatial
domain {\tt newDom}. Its contents are stored in \Ref{BLOBTile}
{\tt newBLOBTile}. The contents are potentially compressed.
*/
Tile(const Tile& tile);
/// constructs a TransTile joined out of the Tiles in {\tt tilesVec}.
Tile(std::vector* tilesVec);
/*@Doc:
Constructs a new Tile out of the vector {\tt tilesVec}
containing pointers to tiles. The Tile created has the
closure of the domains of all tiles in the vector as it's domain
and the same base type. The tiles should not overlap and must have
the same basetype and dimension. Non filled areas in the created
tile are of undefined value. The contents are copied, the memory
of the tiles and the vector has to be freed by the caller. The
resulting Tile is by default uncompressed.
*/
/*@ManMemo:
constructs a Tile with the domain {\tt resDom}
and the contents joined out of the Tiles in {\tt tilesVec}.
*/
Tile(std::vector* tilesVec, const r_Minterval& resDom);
/*@Doc:
Constructs a new Tile out of the vector {\tt tilesVec}
containing pointers to tiles. The contents which fall in the area
{\tt resDom} are copied into the new Tile. The Tile
created has the domain {\tt resDom} and the same base type as the
Tiles in {\tt tilesVec}. The tiles should not overlap and must
have the same basetype and dimension. Non filled areas in the
created tile are of undefined value. The memory of the tiles and
the vector has to be freed by the caller. Every tile in {\tt
tilesVec} has to overlap with {\tt resDom}.
*/
/// constructs Tile as projection of {\tt projTile}.
Tile(const Tile* projTile, const r_Minterval& projDom, const std::set >* projDim);
/*@Doc:
Constructs a new Tile out of the projection of Tile {\tt
projTile} with the dimensions given in {\tt projDim} projected
away (zero based dimension counting!). Only the area specified in
projDom is used for the new Tile. {\tt projDom} must have the
same dimension as the domain of {\tt projTile}. Dimensions
projected away must have the coordinate to be projected at
as domain, e.g. 28:28.
*/
/*@ManMemo: constructs a Tile with base type {\tt newType} and
spatial domain {\tt newDom}. */
Tile(const r_Minterval& newDom, const BaseType* newType, r_Data_Format newFormat = r_Array);
/*@Doc
The contents are undefined! This constructor should usually not
be used.
*/
/// constructs a Tile with contents {\tt newCells}.
Tile(const r_Minterval& newDom, const BaseType* newType, char* newCells, r_Bytes newSize = 0, r_Data_Format newFormat = r_Array);
/*Doc
Constructs a new Tile with basetype {\tt newType} and spatial
domain {\tt newDom}. The char array {\tt newCells} contains the
potentially compressed contents of the new Tile. The memory for
the cells is managed by Tile and has to be allocated with
malloc(). If newSize is 0, it is assumed to be uncompressed contents,
and the size is calculated from domain and base type.
*/
Tile(const r_Minterval& newDom, const BaseType* newType, const char* newCells, bool, r_Bytes newSize = 0, r_Data_Format newFormat = r_Array);
/*Doc
Constructs a new Tile with basetype {\tt newType} and spatial
domain {\tt newDom}. The char array {\tt newCells} contains the
potentially compressed contents of the new Tile. 'bool' is used only,
for making the difference between this constructor and the upper one.
This one doesn't delete the passed data!
If newSize is 0, it is assumed to be uncompressed contents,
and the size is calculated from domain and base type.
*/
//@Man: read methods
//@{
/// returns the spatial domain of the tile.
const r_Minterval& getDomain() const;
/// returns the BaseType of the tile.
const BaseType* getType() const;
/// returns the dimension of the tile.
r_Dimension getDimension() const;
/// returns size of the (uncompressed) contents of the tile in chars.
r_Bytes getSize() const;
/// returns size of the contents of the tile as stored in chars.
r_Bytes getCompressedSize() const;
/// returns the format of the data maintained by the tile
r_Data_Format getDataFormat() const;
/// returns true for persistent instances.
bool isPersistent() const;
/// returns true if the contents are currently compressed and must be decompressed in order to be usefull
bool isCompressed() const;
//@}
//@Man: functions to reading and writing the content.
//@{
/// access to cell for reading (index is 1D) one cell length is basetype length.
const char* getCell(r_Area index) const;
/// access to cell for modifying (index is 1D).
char* getCell(r_Area index);
/// set cell (index is 1D).
void setCell(r_Area index, const char* newCell);
/// access to a cell using an r_Point.
char* getCell(const r_Point& aPoint);
/// access to a cell using an r_Point.
const char* getCell(const r_Point& aPoint) const;
/// returns pointer to (uncompressed) contents of Tile.
const char* getContents() const;
/// returns pointer to (uncompressed) contents of Tile.
char* getContents();
/// sets (uncompressed) contents of Tile.
void setContents(char* newContents);
/*@Doc:
The memory for the cells is managed by the Tile and has to be
allocated with malloc(). Its size has to be correct according to
domain and base type of the Tile.
*/
/// returns pointer to compressed contents of Tile as stored.
const char* getCompressedContents() const;
/// returns pointer to potentially compressed contents of Tile as stored.
const r_Tile_Compression* getCompressionEngine() const;
/// this is a quick hack for BLVA (r_RLE seems not to work on DEC)
void setCompressionEngine(r_Tile_Compression* newCompEngine);
/// this is a quick hack for BLVA (r_RLE seems not to work on DEC)
void setCompressionFormat(r_Data_Format newFormat);
//@}
//@Man: functions related to compression
//@{
/// set parameters for compression/decompression
void setParameters(const char *par);
/// get compression/decompression parameters
const char *getParameters(void) const;
/// make sure the tile is compressed
void compress() const;
/// make sure the tile is decompressed
/// returns true if no errors were encountered and false if black data was generated
bool decompress() const;
//@}
/// printed output for testing.
void printStatus(unsigned int level = 0, std::ostream &stream = std::cout) const;
/*@Doc:
Prints the contents of the Tile on stream. Prints every cell in
the Tile with the {\tt printCell} function of the \Ref{BaseType}.
For dimensionality > 1, 2D-slices are printed with an empty line
in between. These 2D slices cover the lowest 2 indices (0 and 1).
*/
void setPersistent(bool state = true);
/// splits tile in vector of tiles of smaller size.
std::vector* splitTile(r_Minterval resDom, int storageDomain = 0);
/*@Doc:
The Tile is split into subtiles with the same extent as {\tt
resDom}. The storage domain (pers. or transient) of the subtiles is
defined by {\tt storageDomain}. If it is null (default value) they
have the same type (\Ref{TransTile} resp. \Ref{Tile}) as self.
If {\tt storageDomain} is 1, they are persistent, if {\tt storageDomain}
has a value other than 0 or 1, they are made transient.
The algoritm starts with the smallest
coordinate in each dimension, so that if the Tile does not divide
into Tiles of extent {\tt resDom}, the last Tiles in each
dimension may be smaller. The Tiles returned as pointers have to
be freed by the caller!
*/
//@Man: methods for carrying out operations
//@{
/// carries out condense function (const)
char* execCondenseOp(CondenseOp* myOp, const r_Minterval& areaOp);
/*@Doc:
The condense function {\tt myOp} is applied to all cells of self in
the area {\tt areaOp}. The result is stored in myOp which also
gives the start value for the condense operation. The return value
is a pointer to a member of myOp, so it gets invalid if myOp is
deleted! For further information on condense operations see \Ref{Ops}.
*/
/// carries out unary function with self as result.
void execUnaryOp(UnaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp);
/*@Doc:
The unary function {\tt myOp} is applied to all cells of the tile
{\tt opTile} in the area {\tt areaOp}. The result of the
operation is stored in self in the area {\tt areaRes}. The areas
must have the same extent, but may differ in an offset.
*/
/// carries out binary function with self as result.
void execBinaryOp( BinaryOp* myOp, const r_Minterval& areaRes,
const Tile* op1Tile, const r_Minterval& areaOp1,
const Tile* op2Tile, const r_Minterval& areaOp2);
/*@Doc:
The binary function {\tt myOp} is applied to all cells of the tiles
{\tt op1Tile} and {\tt op2Tile} in the respective areas. The
result of the operation is stored in self in the area {\tt
areaRes}. The areas must have the same extent for all tiles. but
may differ in an offset vector.
*/
/// carries out binary function with self as result.
virtual void execConstOp( BinaryOp* myOp, const r_Minterval& areaRes,
const Tile* opTile, const r_Minterval& areaOp,
const char* cell, int constPos = 1);
/*@Doc:
The binary function {\tt op} is applied to all cells of the tile
{\tt op1Tile} and the constant {\tt cell} in the area {\tt
areaOp}. If {\tt constPos} is 1, then {\tt const op cell} is
carried out; if it is 2, then {\tt cell op const} is carried out.
The result of the operations is stored in self in the area {\tt
areaRes}. {\tt areaOp} and {\tt areaRes} must have the same
extent, but may differ in an offset.
*/
/// fills tile in area {\tt areaRes} using MarrayOp {\tt myOp}.
virtual void execMarrayOp(MarrayOp* myOp, const r_Minterval& areaRes, const r_Minterval& areaOp);
/*@Doc:
{\tt myOp} maps a point to a value. It is important that the base
type specified it the same as the tile has.
*/
/// executes general condense operation {\tt myOp} in area {\tt areaOp} (const)
static char* execGenCondenseOp(GenCondenseOp* myOp, const r_Minterval& areaOp);
/*@Doc:
{\tt myOp} maps a point to a value. The return values has the resType
defined in {\tt myOp}. The tile is not accessed (static function),
the function is defined here to be located together with the other
operation execution functions.
*/
/// executes scaling operation.
virtual void execScaleOp( const Tile* opTile, const r_Minterval& areaOp,
const r_Point& origin,
const std::vector& scaleFactors);
/*@Doc:
The tile {\tt opTile} is scaled down in each dimension by the
corresponding element in vector {\tt scaleFactors}. The result
is stored in the tile on which the operation is called. Scaling
is done by using a nearest neighbour algorithm based on
{\tt origin} as the point where the scaling process started.
{\tt opTile} has to have the same dimensionality as the result
tile and scaleFactors has to have a corresponding number of
elements.
*/
//@}
/// return spatial domain of result tile for scaling in areaScaled.
/// return 0 if the result tile will be empty.
/// (the same function, but with implicit origin (0,0,...0) and working fine!)
int scaleGetDomain( const r_Minterval& areaOp,
const std::vector& scaleFactors,
r_Minterval& areaScaled);
/*@Doc:
Return result domain in areaScaled if scaling using the factors in
scaleFactors would be applied in area {\tt areaOp} with the scaling
factors specified in {\tt scaleFactors}. If the tile would become
completely empty, false is returned. This can then be used to create
a temporary tile for the result on which the {\tt execScaleOp}
function can be called.
*/
/// virtual destructor.
virtual ~Tile();
/// copy a subcube from one tile to another
virtual void copyTile(const r_Minterval& areaRes, const Tile *opTile, const r_Minterval& areaOp);
/*@Doc:
The part of opTile covered by areaOp is copied to areaRes of this tile. Identical in functionality to execUnaryOp(OP_IDENTITY, ...) but much faster.
Requires matching base types and matching domains.
*/
DBTileId getDBTile();
/*Doc
Returns a pointer to the \Ref{BLOBTile} holding the contents of
the Tile. This function is used to persistently store the
contents of a Tile.
*/
#ifdef RMANBENCHMARK
// RMTimer for taking O2 times. Could be protected. Is controlled
// in servercomm/servercomm2.cc.
static RMTimer opTimer;
static RMTimer relTimer;
#endif
protected:
//@Man: utility functions used internally.
//@{
/// calculate offset in cells
r_Bytes calcOffset(const r_Point& point) const;
// fill cells of size size with pattern newCell of size patSize.
/// instantiate a compression engine
void initCompEngine() const;
//@}
/// spatial domain of the tile.
r_Minterval domain;
/// pointer to base type for cells of Tile.
const BaseType* type;
/// Smart pointer to the persistent BLOBTile.
DBTileId blobTile;
/// The compression algorithm
mutable r_Tile_Compression *compEngine;
/// compression parameters
char* params;
};
#endif