summaryrefslogtreecommitdiffstats
path: root/indexmgr/mddobjix.hh
blob: b79b5213bb72304219674620b33ba85ffd85fb4a (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
/*
* 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>.
*/

#ifndef _MDDOBJIX_HH_
#define _MDDOBJIX_HH_

class PersTile;
class BaseType;
class Tile;
class r_Point;
#include "raslib/minterval.hh"
#include "raslib/rmdebug.hh"
#include "indexmgr/indexds.hh"
#include "storagemgr/sstoragelayout.hh"
#include "reladminif/lists.h"
#include "relindexif/indexid.hh"
#include <vector>


/****************************************************************************
 *
 *
 * INCLUDE: mddobjix.hh
 *
 * MODULE:  indexmgr
 * CLASS:   MDDObjIx
 *
 *
 * COMMENTS:
 *     none
 *
 ****************************************************************************/

/**
 *	@file mddobjix.hh
 *
 *	@ingroup indexmgr
 */


/*@Doc:
      
Each MDD Object is composed of a set of tiles which are accessed through an index.
The task of the index is to determine the tiles affected by a spatial operation and to allow fast access to them.  It will also take care of memory management of the tiles.

{\bfMDD Objects indexes: }

MDD Objects indexes are multidimensional since they provide access to multidimensional rectangular tiles existing in multidimensional intervals. An MDDObjIx has to be able to deal with different dimensionalities. 

The index of an MDD object keeps the information about the current domain of the MDD object. During the lifetime of the object, it is possible that the definition (or current) domain of an object is not completely covered by the tiles already inserted. 
At each moment, the current domain of an object is the closure of the domains of all tiles. All tiles should be completely contained 
in the definition domain of an object. 
The definition domain may have open boundaries, but the current domain is always a closed interval.

The lower classes in the indexmgr support storage of any kind of persistent object.
This class has to be changed to reflect this aability.

     In the future, functions have to be implemented which allow the user 
     to give indication about priorities for freeing tiles from main memory. 
     
*/

//function pointer to the static function which inserts objects
typedef bool (*IxLogic_insertObject) (IndexDS* theIx, const KeyObject& theObj, const StorageLayout& sl);

//function pointer to the static function which removes objects
typedef bool (*IxLogic_removeObject) (IndexDS* theIx, const KeyObject& theObj, const StorageLayout& sl);

//function pointer to the static function which gets objects from the index
typedef void (*IxLogic_intersect) (const IndexDS* theIx, const r_Minterval& searchInterval, KeyObjectVector& objs, const StorageLayout& sl);

//function pointer to the static function which gets object at point
typedef void (*IxLogic_containPointQuery) (const IndexDS* theIx, const r_Point& searchPoint, KeyObject& result, const StorageLayout& sl);

//function pointer to the static function which inserts objects
typedef void (*IxLogic_getObjects) (const IndexDS* theIx, KeyObjectVector& objs, const StorageLayout& sl);

class MDDObjIx             
	{ 
	public:

		MDDObjIx(const StorageLayout& sl, const r_Minterval& dom, const BaseType* bt = 0);
		/*@Doc:
			When bt is NULL this index will behave as if it were a transient index.
		*/

		MDDObjIx(DBObjectId newDBIx, const StorageLayout& sl, const BaseType* bt);
		/*@Doc:
			When bt is NULL this index will behave as if it were a transient index.
		*/

		void printStatus(unsigned int level = 0, std::ostream& stream = std::cout) const;
	
		~MDDObjIx();

		DBObjectId getDBMDDObjIxId() const;

		r_Minterval getCurrentDomain() const;

		r_Dimension getDimension() const;

		void insertTile(const Tile* newTile);

		bool removeTile(const Tile *);

		std::vector<Tile *> * intersect(const r_Minterval &) const;

		char* pointQuery(const r_Point& searchPoint);

		const char* pointQuery(const r_Point& searchPoint) const;

		Tile* containPointQuery(const r_Point& searchPoint) const;

		std::vector< Tile* >* getTiles() const;
		
		bool isPersistent() const;
		
		void releasePersTiles();
		/*@Doc:
			This function has to be called by the destructors of persistent subclasses which use the cache, to make sure that the memory for the tiles in the cache is freed.
			This will only have effect on persistent indexes.
			Transient indexes keep their tiles in TransDirIx which deletes its tiles in the destructor.
		*/
		
	protected:

		void setNewLastAccess(const r_Minterval& newLastAccess, const std::vector<Tile*>* newLastTiles);

		void setNewLastAccess(const Tile* newLastTile, bool te = true);
		/*@Doc:
			Add a new tile to the cache and reset the access domain 
			If clear:
				clear the cache
				release all tiles
		*/
		
		std::vector< Tile* >* lastAccessIntersect(const r_Minterval& searchInter) const;
		
		Tile* lastAccessPointQuery(const r_Point& searchPoint) const;
		
		bool removeTileFromLastAccesses(const Tile* tileToRemove);
		/*@Doc:
			Does NOT free tileToRemove allocated memory. Only removes this pointer from lastAccesses list if it finds it there.
			Returns true if found. 
			Subclasses which use the cache must call this function before removing a tile from the index, or else the tile may remain in main memory. 
		*/
		
		r_Minterval lastAccess;
		/*@Doc:
			Either empty interval, if not to search in the cache, or an interval 
			corresponding to the search done the last time. The algorithms which
			search this cache for an intersection take this into account.
			It works simultaneously as a flag and as the specification for the last
			access, if valid.
			Last searched region.
		*/
		
		std::vector< Tile* > lastAccessTiles; 
		/*@Doc:
			Internal cache of {\tt Tile}s accessed the last time.
			Contents change everytime there is an insert, an intersect, a getTiles 
			or a poin query, in the following way:
			- insert: cache invalid, last Access is put to empty interval, 
				lastAccessTiles contains the inserted tiles. This is needed 
				if we want the index to automatically manage the memory 
				allocated for persistent tiles or else the just inserted 
				tiles are immediately invalid for the user after insertion 
				in the object. The lastAccess can not be put to the area 
				because it's impossible to determine the area corresponding 
				to inserted tiles (there may be empty areas and so on, it 
				would be rather complex to calculate these things).
			- intersect/pointquery: cache and lastAccessTiles get the new result. 
						The old access and tiles are thrown away. 
			- getTiles: it would be very inefficient to search here for smaller 
					regions, so lastAccess is made empty and lastAccessTiles 
					contains the tiles accessed (because of PersTiles and 
					automatic management of their memory, they have to be 
					kept by the MDDObjIx).
			For this reason, tiles passed by PersMDDObj are only valid until the 
			next intersect/pointQuery/insert/getTiles operation.
			Alternative implementation for getTiles - always put in the cache 
			correctly.
			Make a check about the search interval and what is in the cache (for 
			example, if cell_count < 90% cache cell count , access index).
			Such a check should also be done in lastAccessPointQuery(): if the 
			cache has more than 10 elements, it is not worth searching in it for 
			a point.
		*/

		const BaseType* cellBaseType;  
		/*@Doc:
			This is needed because the PersTile constructor expects a BaseType.
			It Should be considered to move the creation of PersTiles into the
			MDDObj class.
		*/
		
		
		IndexDS* actualIx;
		/*@Doc:
			The real index structure
		*/
		
		IxLogic_insertObject do_insertObj;
		/*@Doc:
			Function pointer to insert tile logic
		*/

		IxLogic_removeObject do_removeObj;
		/*@Doc:
			Function pointer to remove tile logic
		*/

		IxLogic_intersect do_intersect;
		/*@Doc:
			Function pointer to find tiles logic
		*/

		IxLogic_containPointQuery do_pointQuery;
		/*@Doc:
			Function pointer to find tile logic
		*/

		IxLogic_getObjects do_getObjs;
		/*@Doc:
			Function pointer to get all tiles logic
		*/
		
	#ifdef RMANBENCHMARK

		void initializeTimerPointers();
		/*@Doc:
			This code was commented out because it crashed
		*/
		
		RMTimer *pointQueryTimer;
		RMTimer *intersectTimer;
		RMTimer *getTilesTimer;
	#endif
		void initializeLogicStructure();
		/**
			{\tt actualDBIx} and {\tt cellBaseType} must be already correctly set.
			The function pointers are set according to the index type.
		*/
	
		bool _isPersistent;
		/*@Doc:
			This class is used for both persistent and tranisent objects
			To be able to distinguish whether it is persistent or transient
			this attribute is used.
		*/

		const StorageLayout& myStorageLayout;
		/*@Doc:
			Nifty object which holds information on how to store data in the database.
			It tells you which index to use, hos large a index might become and so on.
		*/
	};

#endif