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 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 
69  sync.m_mutex.lock();
70  for( unsigned int bandIdx = 0 ; bandIdx < sync.m_raster.getNumberOfBands() ;
71  ++bandIdx )
72  {
73  if( maxBlockSizeBytes < (unsigned int)sync.m_raster.getBand( bandIdx )->getBlockSize() )
74  maxBlockSizeBytes = (unsigned int)sync.m_raster.getBand( bandIdx )->getBlockSize();
75  }
76  sync.m_mutex.unlock();
77 
78  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
79  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
80  const double totalVMem = ( (double)te::common::GetTotalVirtualMemory() );
81  const double freeVMem = ( ((double)maxMemPercentUsed) / 100.0 ) *
82  std::min( totalPhysMem, ( totalVMem - usedVMem ) );
83  unsigned int maxNumberOfCacheBlocks = (unsigned int)
84  std::max( 1.0, std::ceil( freeVMem / ((double)maxBlockSizeBytes) ) );
85 
86  return initialize( maxNumberOfCacheBlocks, sync );
87 }
88 
90  const unsigned int maxNumberOfCacheBlocks,
91  RasterSynchronizer& sync )
92 {
93  free();
94 
95  sync.m_mutex.lock();
96 
97  m_syncPtr = &sync;
98 
99  // Finding the global block dimensions
100 
101  unsigned int numberOfRasterBlocks = 0;
102 
103  for( unsigned int bandIdx = 0 ; bandIdx < m_syncPtr->m_raster.getNumberOfBands() ;
104  ++bandIdx )
105  {
106  if( m_globalBlocksNumberX < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx )
107  m_globalBlocksNumberX = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx;
108 
109  if( m_globalBlocksNumberY < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy )
110  m_globalBlocksNumberY = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy;
111 
112  if( m_globalBlockSizeBytes < (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getBlockSize() )
113  m_globalBlockSizeBytes = (unsigned int)m_syncPtr->m_raster.getBand( bandIdx )->getBlockSize();
114 
115  numberOfRasterBlocks +=
116  ( m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksx *
117  m_syncPtr->m_raster.getBand( bandIdx )->getProperty()->m_nblocksy );
118  }
119 
120  // Allocating the internal structures
121 
122  m_maxNumberOfCacheBlocks = std::min( maxNumberOfCacheBlocks, numberOfRasterBlocks );
123  m_maxNumberOfCacheBlocks = std::max( m_maxNumberOfCacheBlocks, 1u );
124 
125  unsigned int blockBIdx = 0;
126  m_blocksPointers.resize( m_syncPtr->m_raster.getNumberOfBands() );
127 
128  for( blockBIdx = 0 ; blockBIdx < m_blocksPointers.size() ; ++blockBIdx )
129  {
130  m_blocksPointers[ blockBIdx ].resize( m_globalBlocksNumberY );
131 
132  for( unsigned int blockYIdx = 0 ; blockYIdx < m_globalBlocksNumberY ;
133  ++blockYIdx )
134  {
135  m_blocksPointers[ blockBIdx ][ blockYIdx ].resize( m_globalBlocksNumberX, 0 );
136  }
137  }
138 
139  sync.m_mutex.unlock();
140 
141  return true;
142 }
143 
145 {
146  // flushing the ram data
147 
148  if( ( m_syncPtr != 0 ) && ( m_syncPtr->m_policy & te::common::WAccess ) )
149  {
150  unsigned int blockBIdx = 0;
151  unsigned int blockYIdx = 0;
152  unsigned int blockXIdx = 0;
153  void* blockPtr = 0;
154 
155  for( blockBIdx = 0 ; blockBIdx < m_blocksPointers.size() ; ++blockBIdx )
156  {
157  for( blockYIdx = 0 ; blockYIdx < m_globalBlocksNumberY ;
158  ++blockYIdx )
159  {
160  for( blockXIdx = 0 ; blockXIdx < m_globalBlocksNumberX ;
161  ++blockXIdx )
162  {
163  blockPtr = m_blocksPointers[ blockBIdx ][ blockYIdx ][ blockXIdx ];
164 
165  if( blockPtr )
166  {
167  if( !m_syncPtr->releaseBlock( blockBIdx, blockXIdx, blockYIdx, blockPtr ) )
168  {
169  throw Exception(TE_TR("Block release error") );
170  }
171  }
172  }
173  }
174  }
175  }
176 
177  m_blocksPointers.clear();
178 
179  unsigned char* blockPtr = 0;
180  for( std::vector< unsigned char* >::size_type blocksHandlerIdx = 0 ;
181  blocksHandlerIdx < m_blocksHandler.size() ; ++blocksHandlerIdx )
182  {
183  blockPtr = m_blocksHandler[ blocksHandlerIdx ];
184  if( blockPtr )
185  {
186  delete[]( blockPtr );
187  }
188  }
189  m_blocksHandler.clear();
190 
191  m_blocksFifo.clear();
192 
193  initState();
194 }
195 
197  unsigned int x, unsigned int y )
198 {
199  assert( m_syncPtr );
200  assert( band < m_syncPtr->m_raster.getNumberOfBands() );
201  assert( x < m_globalBlocksNumberX );
202  assert( y < m_globalBlocksNumberY );
203  assert( x < (unsigned int)m_syncPtr->m_raster.getBand( band )->getProperty()->m_nblocksx );
204  assert( y < (unsigned int)m_syncPtr->m_raster.getBand( band )->getProperty()->m_nblocksy );
205 
206  m_getBlockPointer_BlkPtr = m_blocksPointers[ band ][ y ][ x ];
207 
208  if( m_getBlockPointer_BlkPtr == 0 )
209  {
210  // Is swapp necessary ?
211  if( m_blocksHandler.size() < m_maxNumberOfCacheBlocks )
212  {
213  m_getBlockPointer_BlkPtr = new unsigned char[ m_globalBlockSizeBytes ];
214  m_blocksHandler.push_back( m_getBlockPointer_BlkPtr );
215 
216  // add FIFO information of the new block
217  BlockIndex newBlockFifoIndex;
218  newBlockFifoIndex.m_b = band;
219  newBlockFifoIndex.m_y = y;
220  newBlockFifoIndex.m_x = x;
221  m_blocksFifo.push_back( newBlockFifoIndex );
222  }
223  else
224  {
225  BlockIndex& choosedSwapBlockIndex = m_blocksFifo[
226  m_blocksFifoNextSwapBlockIndex ];
227 
228  m_getBlockPointer_BlkPtr = m_blocksPointers[ choosedSwapBlockIndex.m_b ][
229  choosedSwapBlockIndex.m_y ][ choosedSwapBlockIndex.m_x ];
230  assert( m_getBlockPointer_BlkPtr );
231  m_blocksPointers[ choosedSwapBlockIndex.m_b ][
232  choosedSwapBlockIndex.m_y ][ choosedSwapBlockIndex.m_x ] = 0;
233 
234  // writing the block choosed for swap, if necessary
235 
236  if( !m_syncPtr->releaseBlock( choosedSwapBlockIndex.m_b,
237  choosedSwapBlockIndex.m_x, choosedSwapBlockIndex.m_y, m_getBlockPointer_BlkPtr ) )
238  {
239  throw Exception(TE_TR("Block release error") );
240  }
241 
242  // advances the next swap block fifo index
243  choosedSwapBlockIndex.m_b = band;
244  choosedSwapBlockIndex.m_y = y;
245  choosedSwapBlockIndex.m_x = x;
246  m_blocksFifoNextSwapBlockIndex = ( m_blocksFifoNextSwapBlockIndex + 1 ) %
247  ((unsigned int)m_blocksFifo.size());
248  }
249 
250  // reading the required block
251 
252  if( !m_syncPtr->acquireBlock( band, x, y, m_getBlockPointer_BlkPtr ) )
253  {
254  throw Exception(TE_TR("Block release error") );
255  }
256 
257  m_blocksPointers[ band ][ y ][ x ] = m_getBlockPointer_BlkPtr;
258 
259  }
260 
261  return m_getBlockPointer_BlkPtr;
262 }
263 
265 {
266  if( m_syncPtr )
267  {
268  return &(m_syncPtr->m_raster);
269  }
270  else
271  {
272  return 0;
273  }
274 }
275 
276 
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:347
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:428
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).
virtual int getBlockSize() const
It returns the number of bytes ocuppied by a data block.
Definition: Band.cpp:630
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...