summaryrefslogtreecommitdiffstats
path: root/tilemgr/tile.hh
blob: 05cd2ccb0878ae1302498cae8df58c21bbbe6aec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see <http://www.rasdaman.org>
* or contact Peter Baumann via <baumann@rasdaman.com>.
*/

/*************************************************************
 *
 *
 * PURPOSE:
 *   Tile is the abstract base class for persTile, transTile
 *   and constTile
 *
 *
 * COMMENTS:
 *
 ************************************************************/

#ifndef _TILE_HH_
#define _TILE_HH_

#include <vector>
#include <set>

#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<Tile*>* 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<Tile*>* 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<r_Dimension, std::less<r_Dimension> >* 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<Tile*>* 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<double>& 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<double>& 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