All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SynchronizedBandBlocksManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/raster/SynchronizedBandBlocksManager.cpp
22 
23  \brief Synchronized raster raster band blocks manager.
24 */
25 
26 // TerraLib
27 
28 #include "../raster/Band.h"
29 #include "../raster/BandProperty.h"
31 #include "Exception.h"
32 #include "../common/PlatformUtils.h"
33 #include "../common/Translator.h"
34 
35 // STL
36 #include <algorithm>
37 #include <climits>
38 
40 {
41  m_syncPtr = 0;
48 }
49 
51 {
52  initState();
53 }
54 
56 {
57  free();
58 }
59 
61  RasterSynchronizer& sync, const unsigned char maxMemPercentUsed )
62 {
63  free();
64 
65  // Finding the global block dimensions
66 
67  unsigned int maxBlockSizeBytes = 0;
68  unsigned int maxNumberOfCacheBlocks = 1;
69 
70  if( !( sync.m_policy & te::common::WAccess ) )
71  {
72  sync.m_mutex.lock();
73  for( unsigned int bandIdx = 0 ; bandIdx < sync.m_raster.getNumberOfBands() ;
74  ++bandIdx )
75  {
76  if( maxBlockSizeBytes < (unsigned int)sync.m_raster.getBand( bandIdx )->getBlockSize() )
77  maxBlockSizeBytes = (unsigned int)sync.m_raster.getBand( bandIdx )->getBlockSize();
78  }
79  sync.m_mutex.unlock();
80 
81  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
82  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
83  const double totalVMem = ( (double)te::common::GetTotalVirtualMemory() );
84  const double freeVMem = ( ((double)maxMemPercentUsed) / 100.0 ) *
85  std::min( totalPhysMem, ( totalVMem - usedVMem ) );
86  maxNumberOfCacheBlocks = (unsigned int)
87  std::max( 1.0, std::ceil( freeVMem / ((double)maxBlockSizeBytes) ) );
88  }
89 
90  return initialize( maxNumberOfCacheBlocks, sync );
91 }
92 
94  const unsigned int maxNumberOfCacheBlocks,
95  RasterSynchronizer& sync )
96 {
97  free();
98 
99  sync.m_mutex.lock();
100 
101  m_syncPtr = &sync;
102 
103  // Finding the global block dimensions
104 
105  unsigned int numberOfRasterBlocks = 0;
106 
107  for( unsigned int bandIdx = 0 ; bandIdx < m_syncPtr->m_raster.getNumberOfBands() ;
108  ++bandIdx )
109  {
110  if( m_globalBlocksNumberX < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx )
111  m_globalBlocksNumberX = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx;
112 
113  if( m_globalBlocksNumberY < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy )
114  m_globalBlocksNumberY = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy;
115 
116  if( m_globalBlockSizeBytes < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getBlockSize() )
117  m_globalBlockSizeBytes = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getBlockSize();
118 
119  numberOfRasterBlocks +=
120  ( m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx *
121  m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy );
122  }
123 
124  // Allocating the internal structures
125 
126  if( sync.m_policy & te::common::WAccess )
127  {
128  m_maxNumberOfCacheBlocks = std::min( numberOfRasterBlocks, 1u );
129  }
130  else
131  {
132  m_maxNumberOfCacheBlocks = std::min( maxNumberOfCacheBlocks, numberOfRasterBlocks );
133  m_maxNumberOfCacheBlocks = std::max( m_maxNumberOfCacheBlocks, 1u );
134  }
135 
136  unsigned int blockBIdx = 0;
137  m_blocksPointers.resize( m_syncPtr->m_raster.getNumberOfBands() );
138 
139  for( blockBIdx = 0 ; blockBIdx < m_blocksPointers.size() ; ++blockBIdx )
140  {
141  m_blocksPointers[ blockBIdx ].resize( m_globalBlocksNumberY );
142 
143  for( unsigned int blockYIdx = 0 ; blockYIdx < m_globalBlocksNumberY ;
144  ++blockYIdx )
145  {
146  m_blocksPointers[ blockBIdx ][ blockYIdx ].resize( m_globalBlocksNumberX, 0 );
147  }
148  }
149 
150  sync.m_mutex.unlock();
151 
152  return true;
153 }
154 
156 {
157  // flushing the ram data
158 
159  if( ( m_syncPtr != 0 ) && ( m_syncPtr->m_policy & te::common::WAccess ) )
160  {
161  unsigned int blockBIdx = 0;
162  unsigned int blockYIdx = 0;
163  unsigned int blockXIdx = 0;
164  void* blockPtr = 0;
165 
166  for( blockBIdx = 0 ; blockBIdx < m_blocksPointers.size() ; ++blockBIdx )
167  {
168  for( blockYIdx = 0 ; blockYIdx < m_globalBlocksNumberY ;
169  ++blockYIdx )
170  {
171  for( blockXIdx = 0 ; blockXIdx < m_globalBlocksNumberX ;
172  ++blockXIdx )
173  {
174  blockPtr = m_blocksPointers[ blockBIdx ][ blockYIdx ][ blockXIdx ];
175 
176  if( blockPtr )
177  {
178  if( !m_syncPtr->releaseBlock( blockBIdx, blockXIdx, blockYIdx, blockPtr ) )
179  {
180  throw Exception(TE_TR("Block release error") );
181  }
182  }
183  }
184  }
185  }
186  }
187 
188  m_blocksPointers.clear();
189 
190  unsigned char* blockPtr = 0;
191  for( std::vector< unsigned char* >::size_type blocksHandlerIdx = 0 ;
192  blocksHandlerIdx < m_blocksHandler.size() ; ++blocksHandlerIdx )
193  {
194  blockPtr = m_blocksHandler[ blocksHandlerIdx ];
195  if( blockPtr )
196  {
197  delete[]( blockPtr );
198  }
199  }
200  m_blocksHandler.clear();
201 
202  m_blocksFifo.clear();
203 
204  initState();
205 }
206 
208  unsigned int x, unsigned int y )
209 {
210  assert( m_syncPtr );
211  assert( band < m_syncPtr->m_raster.getNumberOfBands() );
212  assert( x < m_globalBlocksNumberX );
213  assert( y < m_globalBlocksNumberY );
214  assert( x < (unsigned int)m_syncPtr->m_raster.getBand( band )->getProperty()->m_nblocksx );
215  assert( y < (unsigned int)m_syncPtr->m_raster.getBand( band )->getProperty()->m_nblocksy );
216 
217  m_getBlockPointer_BlkPtr = m_blocksPointers[ band ][ y ][ x ];
218 
219  if( m_getBlockPointer_BlkPtr == 0 )
220  {
221  // Is swapp necessary ?
222  if( m_blocksHandler.size() < m_maxNumberOfCacheBlocks )
223  {
224  m_getBlockPointer_BlkPtr = new unsigned char[ m_globalBlockSizeBytes ];
225  m_blocksHandler.push_back( m_getBlockPointer_BlkPtr );
226 
227  // add FIFO information of the new block
228  BlockIndex newBlockFifoIndex;
229  newBlockFifoIndex.m_b = band;
230  newBlockFifoIndex.m_y = y;
231  newBlockFifoIndex.m_x = x;
232  m_blocksFifo.push_back( newBlockFifoIndex );
233  }
234  else
235  {
236  BlockIndex& choosedSwapBlockIndex = m_blocksFifo[
237  m_blocksFifoNextSwapBlockIndex ];
238 
239  m_getBlockPointer_BlkPtr = m_blocksPointers[ choosedSwapBlockIndex.m_b ][
240  choosedSwapBlockIndex.m_y ][ choosedSwapBlockIndex.m_x ];
241  assert( m_getBlockPointer_BlkPtr );
242  m_blocksPointers[ choosedSwapBlockIndex.m_b ][
243  choosedSwapBlockIndex.m_y ][ choosedSwapBlockIndex.m_x ] = 0;
244 
245  // writing the block choosed for swap, if necessary
246 
247  if( !m_syncPtr->releaseBlock( choosedSwapBlockIndex.m_b,
248  choosedSwapBlockIndex.m_x, choosedSwapBlockIndex.m_y, m_getBlockPointer_BlkPtr ) )
249  {
250  throw Exception(TE_TR("Block release error") );
251  }
252 
253  // advances the next swap block fifo index
254  choosedSwapBlockIndex.m_b = band;
255  choosedSwapBlockIndex.m_y = y;
256  choosedSwapBlockIndex.m_x = x;
257  m_blocksFifoNextSwapBlockIndex = ( m_blocksFifoNextSwapBlockIndex + 1 ) %
258  ((unsigned int)m_blocksFifo.size());
259  }
260 
261  // reading the required block
262 
263  if( !m_syncPtr->acquireBlock( band, x, y, m_getBlockPointer_BlkPtr ) )
264  {
265  throw Exception(TE_TR("Block release error") );
266  }
267 
268  m_blocksPointers[ band ][ y ][ x ] = m_getBlockPointer_BlkPtr;
269 
270  }
271 
272  return m_getBlockPointer_BlkPtr;
273 }
274 
276 {
277  if( m_syncPtr )
278  {
279  return &(m_syncPtr->m_raster);
280  }
281  else
282  {
283  return 0;
284  }
285 }
286 
287 
RasterSynchronizer * m_syncPtr
A pointer to the synchronizer used by this instance, of null if not initialized.
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
An access synchronizer to be used in SynchronizedRaster raster instances.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
unsigned int m_blocksFifoNextSwapBlockIndex
The next block swapp index over m_blocksFifo.
boost::mutex m_mutex
General sync mutex;.
void initState()
Initialize this instance to an initial state.
unsigned int m_maxNumberOfCacheBlocks
The maximum number of cache blocks.
An exception class for the Raster module.
Raster & m_raster
The input raster.
TECOMMONEXPORT unsigned long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
An abstract class for raster data strucutures.
Definition: Raster.h:71
BandProperty * getProperty()
Returns the band property.
Definition: Band.cpp:370
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
te::rst::Raster * getRaster() const
Returns the associated raster.
unsigned int m_globalBlockSizeBytes
The maximum block size for all bands.
bool initialize(RasterSynchronizer &sync, const unsigned char maxMemPercentUsed)
Initialize this instance to an initial state.
Synchronized raster raster band blocks manager.
TECOMMONEXPORT unsigned long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
te::common::AccessPolicy m_policy
The access policy used on the given input raster.
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:572
unsigned int m_globalBlocksNumberY
The maximum number of blocks (Y axis) for all bands.
void * getBlockPointer(unsigned int band, unsigned int x, unsigned int y)
Returns a pointer to the required data block.
unsigned int m_globalBlocksNumberX
The maximum number of blocks (X axis) for all bands.
TECOMMONEXPORT unsigned long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...