Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
hit_blockTile.c
Go to the documentation of this file.
1 
13 /*
14  * <license>
15  *
16  * Hitmap v1.2
17  *
18  * This software is provided to enhance knowledge and encourage progress in the scientific
19  * community. It should be used only for research and educational purposes. Any reproduction
20  * or use for commercial purpose, public redistribution, in source or binary forms, with or
21  * without modifications, is NOT ALLOWED without the previous authorization of the copyright
22  * holder. The origin of this software must not be misrepresented; you must not claim that you
23  * wrote the original software. If you use this software for any purpose (e.g. publication),
24  * a reference to the software package and the authors must be included.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY
27  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29  * THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Copyright (c) 2007-2015, Trasgo Group, Universidad de Valladolid.
37  * All rights reserved.
38  *
39  * More information on http://trasgo.infor.uva.es/
40  *
41  * </license>
42 */
43 
44 #include "hit_blockTile.h"
45 
46 /* A. INITIALIZE DOMAIN */
47 void hit_blockTileNew( HitBlockTile *container, void *originalVar, int blockSizes[ HIT_MAXDIMS ] ) {
48  HitTile *original = (HitTile *)originalVar;
49 
50  /* 1. GENERATE NEW SHAPE: COMPUTE NUMBER OF BLOCKS PER DIMENSION */
51  // ASSIGN THE ORIGINAL DOMAIN SHAPE, AND REDUCE THE SIGNATURE ON EACH DIMENSION
52  HitShape blocksShape = hit_tileShape( *original );
53  int dim;
54  for ( dim=0; dim < hit_tileDims( *original ); dim++ ) {
55  int numBlocks = (int)ceil( (double)hit_shapeSigCard( blocksShape, dim ) / blockSizes[dim] );
56  hit_shapeSig( blocksShape, dim ) = hit_sigStd( numBlocks );
57  }
58 
59  /* 2. CREATE CONTAINER TILE */
60  hit_tileDomainShape( container, HitTile, blocksShape );
61 
62  /* 3. FILL UP CHILD-SIZES WITH BLOCK SIZES */
63  for ( dim=0; dim < hit_tileDims( *original ); dim++ ) {
64  container->childSize[dim] = blockSizes[dim];
65  }
66 
67  /* 4. REFERENCE POINTER TO THE ORIGINAL VARIABLE */
68  container->ref = (HitBlockTile *)original;
69 
70  /* 5. END */
71 }
72 
73 
74 /* B. ALLOC FUNCTION */
75 void hit_blockTileAllocInternal( HitBlockTile *container, size_t baseSizeExtent, void *fillValue ) {
76 
77  /* 0. NULL SHAPES, SKIP */
78  if ( hit_tileDims( *container ) < 1 ) return;
79 
80  /* 1. CREATE BASIC BLOCK AND FILL CONTAINER */
81  /* 1.1. GENERATE A BLOCK WITH A SHAPE EXTRACTED FROM CONTAINER INFORMATION */
82  HitShape blockShape = HIT_SHAPE_NULL;
83  hit_shapeDimsSet( blockShape, hit_tileDims( *container ) );
84  int dim;
85  for ( dim=0; dim < hit_tileDims( *container ); dim++ ) {
86  hit_shapeSig( blockShape, dim ) = hit_sigStd( container->childSize[dim] );
87  }
88 
89  HitTile block;
90  // FAKE THE UNKNOWN BASE TYPE WITH ANY FOO TYPE, CHANGE DE BASE EXTENT AFTERWARDS
91  hit_tileDomainShape( &block, char, blockShape );
92  block.baseExtent = baseSizeExtent;
93 
94  /* 1.2. ALLOCATE AND FILL THE BLOCK AND CONTAINER */
95  hit_tileAlloc( &block );
96  if ( fillValue != NULL ) hit_tileFill( &block, fillValue );
97  hit_tileAlloc( container );
98  hit_tileFill( container, &block );
99  hit_tileFree( block );
100 
101  /* 2. PROCESS BLOCKS WITH PADDING */
102  /* (Particular methods for 1D or 2D arrays. It will become obsolete in version 1.2) */
103 
104  /* 2.0. LOCATE THE ORIGINAL DOMAIN AND REFERENCE MBTILE FOR SELECTIONS */
105  HitTile *original;
106  HitTile *fullBlockTile = NULL;
107  for ( original = (HitTile*)container;
108  original->ref != NULL;
109  original = (HitTile*)original->ref )
110  if ( original->hierDepth != HIT_NONHIERARCHICAL ) fullBlockTile = original;
111 
112  /* 2.1. 1D-ARRAYS */
113  if ( hit_tileDims( *container ) == 1 ) {
114  int lastElement = hit_tileDimCard( *(original), 0 );
115  int lastBlockSize = lastElement % container->childSize[0];
116  if ( lastBlockSize != 0 ) {
117  // IF THE LAST BLOCK IS NOT SELECTED, SKIP
118  if ( hit_tileDimEnd(*container,0) == hit_tileDimEnd(*fullBlockTile,0) ) {
119  // ALLOCATE NEW BLOCK AND COPY THE LAST BLOCK TO NEW ALLOCATION
120  //HitTile *oldLastBlock = (HitTile *) malloc( sizeof(HitTile) );
121  //if ( oldLastBlock == NULL ) hit_errInternal(__FUNCTION__, "Allocating padded blocks", "", __FILE__, __LINE__ );
122  HitTile *lastBlock = &( container->data[ container->acumCard-1 ] );
123  //*oldLastBlock = *lastBlock;
124  lastBlock->unpadded = (HitTile *) malloc( sizeof(HitTile) );
125  if ( lastBlock->unpadded == NULL ) hit_errInternal(__FUNCTION__, "Allocating unpadded blocks", "", __FILE__, __LINE__ );
126 
127  // SELECT, PUT THE RESULT IN THE ORIGINAL POSITION, THE oldLastBlock POINTER POINTS
128  // TO THE NEW ALLOCATED BLOCK WITH THE ORIGINAL BLOCK COPY
129  //hit_tileSelect( lastBlock, oldLastBlock, hit_shape( 1, hit_sigStd(lastBlockSize) ) );
130  hit_tileSelect( lastBlock->unpadded, lastBlock, hit_shape( 1, hit_sigStd(lastBlockSize) ) );
131  }
132  }
133  }
134  /* 2.2. 2D-ARRAYS */
135  else if ( hit_tileDims( *container ) == 2 ) {
136  int lastElement[2];
137  int lastBlockSize[2];
138  for (dim=0; dim<2; dim++) {
139  lastElement[dim] = hit_tileDimCard( *(original), dim );
140  lastBlockSize[dim] = lastElement[dim] % container->childSize[dim];
141  if ( lastBlockSize[dim] != 0 ) {
142  // IF THE LAST BLOCK IS NOT SELECTED, SKIP
143  if ( hit_tileDimEnd(*container,dim) == hit_tileDimEnd(*fullBlockTile,dim) ) {
144  // FOR EACH LAST BLOCK (EXCEPT CORNER BLOCK)
145  int numBlock[2] = { hit_tileDimCard(*container,0)-1, hit_tileDimCard(*container,1)-1 };
146  HitShape noPaddedShape = blockShape;
147  hit_shapeSig( noPaddedShape, dim ) = hit_sigStd(lastBlockSize[dim]);
148 
149  // DETECT IF I HAVE THE CORNER BLOCK TO SKIP IT
150  int cornerBlock =
151  hit_tileDimEnd(*container,0) == hit_tileDimEnd(*fullBlockTile,0)
152  && hit_tileDimEnd(*container,1) == hit_tileDimEnd(*fullBlockTile,1);
153 
154  int invDim = ( dim == 0 ) ? 1:0;
155  for ( numBlock[invDim]=0;
156  // LESS THAN CARDINALITY (-1 TO SKIP CORNER BLOCK IF SELECTED)
157  numBlock[invDim]<hit_tileDimCard(*container, invDim)-cornerBlock;
158  numBlock[invDim]++ ) {
159 
160  // ALLOCATE NEW BLOCK AND COPY THE LAST BLOCK TO NEW ALLOCATION
161  //HitTile *oldLastBlock = (HitTile *) malloc( sizeof(HitTile) );
162  //if ( oldLastBlock == NULL ) hit_errInternal(__FUNCTION__, "Allocating padded blocks", "", __FILE__, __LINE__ );
163  HitTile *lastBlock = &( hit_tileGet(*container, 2, numBlock[0], numBlock[1] ) );
164  //*oldLastBlock = *lastBlock;
165  lastBlock->unpadded = (HitTile *) malloc( sizeof(HitTile) );
166  if ( lastBlock->unpadded == NULL ) hit_errInternal(__FUNCTION__, "Allocating unpadded blocks", "", __FILE__, __LINE__ );
167 
168  // SELECT, PUT THE RESULT IN THE ORIGINAL POSITION, THE old POINTER POINTS
169  // TO THE NEW ALLOCATED BLOCK WITH THE ORIGINAL BLOCK COPY
170  //hit_tileSelect( lastBlock, oldLastBlock, noPaddedShape );
171  hit_tileSelect( lastBlock->unpadded, lastBlock, noPaddedShape );
172  }
173  }
174  }
175  // KEEP THE BLOCK SIZE FOR USING IT ON CORNER BLOCK SHAPE
176  else lastBlockSize[dim] = container->childSize[dim];
177  }
178  // CORNER WITH PADDING IN ANY DIMENSION
179  if ( lastBlockSize[0] != 0 || lastBlockSize[1] != 0 ) {
180  // IF THE LAST BLOCK IS NOT SELECTED, SKIP
181  if ( hit_tileDimEnd(*container,0) == hit_tileDimEnd(*fullBlockTile,0)
182  && hit_tileDimEnd(*container,1) == hit_tileDimEnd(*fullBlockTile,1)
183  ) {
184  // ALLOCATE NEW BLOCK AND COPY THE LAST BLOCK TO NEW ALLOCATION
185  //HitTile *oldLastBlock = (HitTile *) malloc( sizeof(HitTile) );
186  //if ( oldLastBlock == NULL ) hit_errInternal(__FUNCTION__, "Allocating padded blocks", "", __FILE__, __LINE__ );
187  HitTile *lastBlock = &( container->data[ container->acumCard-1 ] );
188  //*oldLastBlock = *lastBlock;
189  lastBlock->unpadded = (HitTile *) malloc( sizeof(HitTile) );
190  if ( lastBlock->unpadded == NULL ) hit_errInternal(__FUNCTION__, "Allocating unpadded blocks", "", __FILE__, __LINE__ );
191 
192  // SELECT, PUT THE RESULT IN THE ORIGINAL POSITION, THE old POINTER POINTS
193  // TO THE NEW ALLOCATED BLOCK WITH THE ORIGINAL BLOCK COPY
194  HitShape noPaddedShape =
195  hit_shape( 2, hit_sigStd(lastBlockSize[0]), hit_sigStd(lastBlockSize[1]) );
196  //hit_tileSelect( lastBlock, oldLastBlock, noPaddedShape );
197  hit_tileSelect( lastBlock->unpadded, lastBlock, noPaddedShape );
198  }
199  }
200  }
201  else hit_warnInternal(__FUNCTION__, "MBTiles not fully implemented for more than 2 dimensions", "", __FILE__, __LINE__ );
202 }
203 
204 /* C. FREE FULL STRUCTURE */
205 void hit_blockTileFree( HitBlockTile container ) {
206 
207  /* 0. SKIP NON-MEMORY-OWNER SELECTIONS */
208  if ( container.memStatus != HIT_MS_OWNER ) return;
209 
210  /* 1. FOR ALL BLOCKS IN THE CONTAINER */
211  int i;
212  for( i=0; i<hit_tileCard( container ); i++ ) {
213  HitTile *block = (HitTile *)( &( container.data[i] ) );
214 
215  /* LOCATE AND FREE MEMORY
216  * PADDED BLOCK -> NOT OWNER
217  * NORMAL BLOCK -> OWNER */
218  //if ( block->memStatus == HIT_MS_NOT_OWNER ) {
219  if ( block->unpadded != NULL ) {
220  //hit_tileFree( *(block->ref) );
221  //free( block->ref ); // FREE ALSO THE ANCESTOR TILE STRUCTURE
222  free ( block->unpadded );
223  }
224  //else hit_tileFree( *block );
225  hit_tileFree( *block );
226  }
227 
228  /* 2. FREE CONTAINER */
229  hit_tileFree( container );
230 }
231 
#define hit_shape(nd,...)
Definition: hit_sshape.h:175
HitShape block[k_num]
Definition: mg.c:156
void hit_blockTileAllocInternal(HitBlockTile *container, size_t baseSizeExtent, void *fillValue)
Definition: hit_blockTile.c:75
#define hit_tileFill(var, value)
Definition: hit_tile.h:390
#define hit_shapeDimsSet(shape, value)
Definition: hit_sshape.h:387
#define hit_tileDims(var)
Definition: hit_tile.h:713
#define hit_tileAlloc(var)
Definition: hit_tile.h:319
#define HIT_MAXDIMS
Definition: hit_shape.h:72
#define hit_tileCard(var)
Definition: hit_tile.h:763
#define hit_tileSelect(newVar, oldVar, shape)
Definition: hit_tile.h:453
#define hit_tileDimCard(var, dim)
Definition: hit_tile.h:750
void hit_blockTileFree(HitBlockTile container)
#define hit_tileDomainShape(newVarP, baseType, shape)
Definition: hit_tile.h:304
HitShape HIT_SHAPE_NULL
Definition: hit_shape.c:60
#define hit_tileDimEnd(var, dim)
Definition: hit_tile.h:796
#define hit_shapeSigCard(shape, dim)
Definition: hit_sshape.h:412
#define hit_warnInternal(routine, text, extraParam, file, numLine)
Definition: hit_error.h:69
#define hit_shapeSig(shape, dim)
Definition: hit_sshape.h:400
#define hit_tileFree(var)
Definition: hit_tile.h:369
void hit_blockTileNew(HitBlockTile *container, void *originalVar, int blockSizes[HIT_MAXDIMS])
Definition: hit_blockTile.c:47
#define hit_errInternal(routine, text, extraParam, file, numLine)
Definition: hit_error.h:63
#define hit_tileShape(var)
Definition: hit_tile.h:723