All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ExpansibleBandBlocksManager.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/dataaccess/memory/ExpansibleBandBlocksManager.cpp
22 
23  \brief RAM cached and tiled raster band blocks manager.
24 */
25 
26 // TerraLib
27 #include "../common/PlatformUtils.h"
28 #include "../common/Translator.h"
29 #include "../raster/Band.h"
30 #include "../raster/BandProperty.h"
31 #include "Exception.h"
33 
34 // STL
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdio>
38 
39 // Boost
40 #include <boost/filesystem.hpp>
41 
42 // ---------------------------------------------------------------------------
43 
45 : m_filePtr( 0 )
46 {
47 }
48 
50 {
51  if( m_filePtr )
52  {
53  remove( m_fullFileName.c_str() );
54  fclose( m_filePtr );
55  }
56 }
57 
58 // ---------------------------------------------------------------------------
59 
61 {
62  m_isInitialized = false;
68 
69 }
70 
72 {
73  initState();
74 }
75 
77 {
78  free();
79 }
80 
82  const unsigned int maxNumberRAMBlocks,
83  const std::vector< unsigned int>& numbersOfBlocksX,
84  const std::vector< unsigned int>& numbersOfBlocksY,
85  const std::vector< unsigned int>& blocksSizesBytes,
86  const unsigned long int maxDiskFilesSize )
87 {
88  if( numbersOfBlocksX.size() == 0 ) return false;
89  if( numbersOfBlocksX.size() != numbersOfBlocksY.size() ) return false;
90  if( numbersOfBlocksY.size() != blocksSizesBytes.size() ) return false;
91 
92  free();
93 
94  m_maxNumberRAMBlocks = maxNumberRAMBlocks;
95  m_maxDiskFilesSize = maxDiskFilesSize;
96 
97  // Discovering boundaries
98 
100  unsigned int maxNumbersOfBlocksX = 0;
101  unsigned int maxNumbersOfBlocksY = 0;
102  unsigned int totalRequiredBlocks = 0;
103 
104  {
105  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
106  ++blockBIdx )
107  {
108  if( blocksSizesBytes[ blockBIdx ] == 0 ) return false;
109 
110  if( m_maxBlockSizeBytes < blocksSizesBytes[ blockBIdx ] )
111  m_maxBlockSizeBytes = blocksSizesBytes[ blockBIdx ];
112 
113  if( numbersOfBlocksX[ blockBIdx ] == 0 ) return false;
114 
115  if( maxNumbersOfBlocksX < numbersOfBlocksX[ blockBIdx ] )
116  maxNumbersOfBlocksX = numbersOfBlocksX[ blockBIdx ];
117 
118  if( numbersOfBlocksY[ blockBIdx ] == 0 ) return false;
119 
120  if( maxNumbersOfBlocksY < numbersOfBlocksY[ blockBIdx ] )
121  maxNumbersOfBlocksY = numbersOfBlocksY[ blockBIdx ];
122 
123  totalRequiredBlocks += ( numbersOfBlocksX[ blockBIdx ] *
124  numbersOfBlocksY[ blockBIdx ] );
125  }
126  }
127 
128  if( m_maxBlockSizeBytes > maxDiskFilesSize ) return false;
129 
130  // Allocating RAM blocks
131 
132  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
133 
134  try
135  {
136  m_ramBlocksPointers.resize( numbersOfBlocksX.size() );
137 
138  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
139  ++blockBIdx )
140  {
141  m_ramBlocksPointers[ blockBIdx ].resize( numbersOfBlocksY[ blockBIdx ] );
142 
143  for( unsigned int blockYIdx = 0 ; blockYIdx < numbersOfBlocksY[ blockBIdx ] ;
144  ++blockYIdx )
145  {
146  m_ramBlocksPointers[ blockBIdx ][ blockYIdx ].resize( numbersOfBlocksX[ blockBIdx ], 0 );
147 
148  for( unsigned int blockXIdx = 0 ; blockXIdx < numbersOfBlocksX[ blockBIdx ] ; ++blockXIdx )
149  {
150  if( m_activeRAMBlocksHandler.size() < maxNumberRAMBlocks )
151  {
152  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
153 
154  m_activeRAMBlocksHandler.push_back( newBlockHandler );
155 
156  m_ramBlocksPointers[ blockBIdx ][ blockYIdx ][ blockXIdx ] =
157  newBlockHandler.get();
158 
159  m_swapFifo.push_back( BlockIndex3D( blockBIdx, blockYIdx, blockXIdx ) );
160  }
161  else
162  {
163  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( blockBIdx,
164  blockYIdx, blockXIdx ) );
165  }
166  }
167  }
168  }
169  }
170  catch(...)
171  {
172  free();
173  return false;
174  }
175 
176  // disk blocks must be used ?
177 
178  try
179  {
180  // allocating the swap block
181 
183 
185 
186  // Allocating disk blocks
187 
188  m_activeDiskBlocksInfo.resize( numbersOfBlocksX.size() );
189 
190  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
191  ++blockBIdx )
192  {
193  m_activeDiskBlocksInfo[ blockBIdx ].resize( numbersOfBlocksY[ blockBIdx ] );
194 
195  for( unsigned int blockYIdx = 0 ; blockYIdx < numbersOfBlocksY[ blockBIdx ] ;
196  ++blockYIdx )
197  {
198  m_activeDiskBlocksInfo[ blockBIdx ][ blockYIdx ].resize( numbersOfBlocksX[ blockBIdx ] );
199  }
200  }
201 
202  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) )
203  {
204  free();
205  return false;
206  }
207  }
208  catch(...)
209  {
210  free();
211  return false;
212  }
213 
214  // finalizing
215 
216  m_isInitialized = true;
217 
218  return true;
219 }
220 
222 {
223  m_activeRAMBlocksHandler.clear();
224  m_ramBlocksPointers.clear();
225  m_swapFifo.clear();
226  m_activeDiskBlocksInfo.clear();
227  m_diskFilesHandler.clear();
228  m_swapBlockHandler.reset();
229 
230  initState();
231 }
232 
234  unsigned int x, unsigned int y )
235 {
236  assert( m_isInitialized );
237 
238  assert( band < m_ramBlocksPointers.size() );
239  assert( y < m_ramBlocksPointers[ band ].size() );
240  assert( x < m_ramBlocksPointers[ band ][ y ].size() );
242 
244  {
246  }
247  else
248  {
249  // defining the blocks that will manipulated
250 
251  assert( m_nextFIFOPositionOverSwapFifo < m_swapFifo.size() );
253 
254  assert( band < m_activeDiskBlocksInfo.size() );
255  assert( y < m_activeDiskBlocksInfo[ band ].size() );
256  assert( x < m_activeDiskBlocksInfo[ band ][ y ].size() );
257  DiskBlockInfo& inDiskInfo = m_activeDiskBlocksInfo[ band ][ y ][ x ];
258 
259  assert( swapIndex.m_dim0Index < m_activeDiskBlocksInfo.size() );
260  assert( swapIndex.m_dim1Index < m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ].size() );
261  assert( swapIndex.m_dim2Index < m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ].size() );
262  DiskBlockInfo& outDiskInfo = m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ][
263  swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ];
264 
265  // reading the required block into m_currSwapBlockPtr
266 
267  assert( inDiskInfo.m_filePtr );
268  if( 0 != fseek( inDiskInfo.m_filePtr,
269  (long)( inDiskInfo.m_fileOff ), SEEK_SET ) )
270  {
271  throw Exception(TE_TR("File seek error") );
272  }
273 
274  assert( m_currSwapBlockPtr != 0 );
275  if( 1 != fread( (void*)m_currSwapBlockPtr, (size_t)( m_maxBlockSizeBytes ),
276  1, inDiskInfo.m_filePtr ) )
277  {
278  throw Exception(TE_TR("File read error") );
279  }
280 
281  // Flushing the choosed tile to disk
282 
283  if( 0 != fseek( inDiskInfo.m_filePtr,
284  (long)( inDiskInfo.m_fileOff ), SEEK_SET ) )
285  {
286  throw Exception(TE_TR("File seek error") );
287  }
288 
289  assert( swapIndex.m_dim0Index < m_ramBlocksPointers.size() );
290  assert( swapIndex.m_dim1Index < m_ramBlocksPointers[ swapIndex.m_dim0Index ].size() );
291  assert( swapIndex.m_dim2Index < m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ].size() );
292  assert( m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ] != 0 );
293  if( 1 != fwrite( (void*)m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ],
294  (size_t)( m_maxBlockSizeBytes ), 1,
295  inDiskInfo.m_filePtr ) )
296  {
297  throw Exception(TE_TR("File write error") );
298  }
299 
300  // updating the indexing structures
301 
303 
304  m_currSwapBlockPtr = m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ];
305 
307 
308  m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ] = 0;
309 
310  swapIndex.m_dim0Index = band;
311  swapIndex.m_dim1Index = y;
312  swapIndex.m_dim2Index = x;
313 
314  outDiskInfo = inDiskInfo;
315 
316  inDiskInfo.m_filePtr = 0;
317  inDiskInfo.m_fileOff = 0;
318 
320  m_swapFifo.size() );
321 
322  // returning the required block pointer
323 
325  }
326 }
327 
329  const unsigned int& expansionSize, const unsigned int& band,
330  std::vector< BlockIndex3D >& addedBlocksCoords )
331 {
332  assert( m_isInitialized );
333  assert( band < m_ramBlocksPointers.size() );
334 
335  addedBlocksCoords.clear();
336 
337  if( expansionSize )
338  {
339  shiftDim03DCoords( m_swapFifo, band, expansionSize, 0 );
340 
341  const unsigned int numberOfBlocksX = (unsigned int)
342  m_ramBlocksPointers[ band ][ 0 ].size();
343 
344  m_ramBlocksPointers[ band ].insert( m_ramBlocksPointers[ band ].begin(),
345  expansionSize,
346  std::vector< BlockelementPtrT >( numberOfBlocksX, 0 ) );
347 
348  m_activeDiskBlocksInfo[ band ].insert( m_activeDiskBlocksInfo[ band ].begin(),
349  expansionSize,
350  std::vector< DiskBlockInfo >( numberOfBlocksX ) );
351 
352  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
353 
354  for( unsigned int blockYIdx = 0 ; blockYIdx < expansionSize ; ++blockYIdx )
355  {
356  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
357  {
359  {
360  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
361 
362  m_activeRAMBlocksHandler.push_back( newBlockHandler );
363 
364  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
365  newBlockHandler.get();
366 
367  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
368  }
369  else
370  {
371  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
372  }
373 
374  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
375  }
376  }
377 
378  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
379  }
380 
381  return true;
382 }
383 
385  const unsigned int& expansionSize, const unsigned int& band,
386  std::vector< BlockIndex3D >& addedBlocksCoords )
387 {
388  assert( m_isInitialized );
389  assert( band < m_ramBlocksPointers.size() );
390 
391  addedBlocksCoords.clear();
392 
393  if( expansionSize )
394  {
395  const unsigned int numberOfBlocksX = (unsigned int)
396  m_ramBlocksPointers[ band ][ 0 ].size();
397 
398  m_ramBlocksPointers[ band ].insert( m_ramBlocksPointers[ band ].end(),
399  expansionSize,
400  std::vector< BlockelementPtrT >( numberOfBlocksX, 0 ) );
401 
402  m_activeDiskBlocksInfo[ band ].insert( m_activeDiskBlocksInfo[ band ].end(),
403  expansionSize,
404  std::vector< DiskBlockInfo >( numberOfBlocksX ) );
405 
406  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
407 
408  for( unsigned int blockYIdx = m_activeDiskBlocksInfo[ band ].size() -
409  expansionSize ; blockYIdx < m_activeDiskBlocksInfo[ band ].size() ;
410  ++blockYIdx )
411  {
412  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
413  {
415  {
416  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
417 
418  m_activeRAMBlocksHandler.push_back( newBlockHandler );
419 
420  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
421  newBlockHandler.get();
422 
423  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
424  }
425  else
426  {
427  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
428  }
429 
430  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
431  }
432  }
433 
434  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
435  }
436 
437  return true;
438 }
439 
441  const unsigned int& expansionSize, const unsigned int& band,
442  std::vector< BlockIndex3D >& addedBlocksCoords )
443 {
444  assert( m_isInitialized );
445  assert( band < m_ramBlocksPointers.size() );
446 
447  addedBlocksCoords.clear();
448 
449  if( expansionSize )
450  {
451  shiftDim03DCoords( m_swapFifo, band, 0, expansionSize );
452 
453  const unsigned int numberOfBlocksY = (unsigned int)
454  m_ramBlocksPointers[ band ].size();
455 
456  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
457 
458  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
459  {
460  m_ramBlocksPointers[ band ][ blockYIdx ].insert(
461  m_ramBlocksPointers[ band ][ blockYIdx ].begin(),
462  expansionSize, BlockelementPtrT( 0 ) );
463 
464  m_activeDiskBlocksInfo[ band ][ blockYIdx ].insert(
465  m_activeDiskBlocksInfo[ band ][ blockYIdx ].begin(),
466  expansionSize, DiskBlockInfo() );
467 
468  for( unsigned int blockXIdx = 0 ; blockXIdx < expansionSize ; ++blockXIdx )
469  {
471  {
472  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
473 
474  m_activeRAMBlocksHandler.push_back( newBlockHandler );
475 
476  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
477  newBlockHandler.get();
478 
479  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
480  }
481  else
482  {
483  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
484  }
485 
486  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
487  }
488  }
489 
490  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
491  }
492 
493  return true;
494 }
495 
497  const unsigned int& expansionSize, const unsigned int& band,
498  std::vector< BlockIndex3D >& addedBlocksCoords )
499 {
500  assert( m_isInitialized );
501  assert( band < m_ramBlocksPointers.size() );
502 
503  addedBlocksCoords.clear();
504 
505  if( expansionSize )
506  {
507  const unsigned int numberOfBlocksY = (unsigned int)
508  m_ramBlocksPointers[ band ].size();
509 
510  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
511 
512  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
513  {
514  m_ramBlocksPointers[ band ][ blockYIdx ].insert(
515  m_ramBlocksPointers[ band ][ blockYIdx ].end(),
516  expansionSize, BlockelementPtrT( 0 ) );
517 
518  m_activeDiskBlocksInfo[ band ][ blockYIdx ].insert(
519  m_activeDiskBlocksInfo[ band ][ blockYIdx ].end(),
520  expansionSize, DiskBlockInfo() );
521 
522  for( unsigned int blockXIdx = m_ramBlocksPointers[ band ][ blockYIdx ].size()
523  - expansionSize ; blockXIdx <
524  m_ramBlocksPointers[ band ][ blockYIdx ].size() ; ++blockXIdx )
525  {
527  {
528  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
529 
530  m_activeRAMBlocksHandler.push_back( newBlockHandler );
531 
532  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
533  newBlockHandler.get();
534 
535  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
536  }
537  else
538  {
539  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
540  }
541 
542  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
543  }
544  }
545 
546  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
547  }
548 
549  return true;
550 }
551 
553  const unsigned int& expansionSize,
554  std::vector< BlockIndex3D >& addedBlocksCoords )
555 {
556  assert( m_isInitialized );
557 
558  addedBlocksCoords.clear();
559 
560  if( expansionSize )
561  {
562  shift3DCoords( m_swapFifo, expansionSize, 0, 0 );
563 
564  const unsigned int numberOfBlocksY = (unsigned int)
565  m_ramBlocksPointers[ 0 ].size();
566  const unsigned int numberOfBlocksX = (unsigned int)
567  m_ramBlocksPointers[ 0 ][ 0 ].size();
568 
569  m_ramBlocksPointers.insert( m_ramBlocksPointers.begin(),
570  expansionSize,
571  std::vector< std::vector< BlockelementPtrT > >( numberOfBlocksY ) );
572 
574  expansionSize,
575  std::vector< std::vector< DiskBlockInfo > >( numberOfBlocksY ) );
576 
577  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
578 
579  for( unsigned int expansionIdx = 0 ; expansionIdx < expansionSize ;
580  ++expansionIdx )
581  {
582  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
583  {
584  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX, 0 );
585  m_activeDiskBlocksInfo[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX );
586 
587  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
588  {
590  {
591  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
592 
593  m_activeRAMBlocksHandler.push_back( newBlockHandler );
594 
595  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ][ blockXIdx ] =
596  newBlockHandler.get();
597 
598  m_swapFifo.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
599  }
600  else
601  {
602  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
603  }
604 
605  addedBlocksCoords.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
606  }
607  }
608  }
609 
610  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
611  }
612 
613  return true;
614 }
615 
616 bool te::mem::ExpansibleBandBlocksManager::addBottomBands( const unsigned int& expansionSize,
617  std::vector< BlockIndex3D >& addedBlocksCoords )
618 {
619  assert( m_isInitialized );
620 
621  addedBlocksCoords.clear();
622 
623  if( expansionSize )
624  {
625  const unsigned int numberOfBlocksY = (unsigned int)
626  m_ramBlocksPointers[ m_ramBlocksPointers.size() - 1 ].size();
627  const unsigned int numberOfBlocksX = (unsigned int)
628  m_ramBlocksPointers[ m_ramBlocksPointers.size() - 1 ][ 0 ].size();
629 
631  expansionSize,
632  std::vector< std::vector< BlockelementPtrT > >( numberOfBlocksY ) );
633 
635  expansionSize,
636  std::vector< std::vector< DiskBlockInfo > >( numberOfBlocksY ) );
637 
638  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
639 
640  for( unsigned int expansionIdx = m_ramBlocksPointers.size() - expansionSize ;
641  expansionIdx < m_ramBlocksPointers.size() ; ++expansionIdx )
642  {
643  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
644  {
645  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX, 0 );
646  m_activeDiskBlocksInfo[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX );
647 
648  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
649  {
651  {
652  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
653 
654  m_activeRAMBlocksHandler.push_back( newBlockHandler );
655 
656  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ][ blockXIdx ] =
657  newBlockHandler.get();
658 
659  m_swapFifo.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
660  }
661  else
662  {
663  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
664  }
665 
666  addedBlocksCoords.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
667  }
668  }
669  }
670 
671  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
672  }
673 
674  return true;
675 }
676 
678  const unsigned int blocksNumber,
679  std::vector< DiskBlockInfo >& diskBlocksInfos,
680  OpenDiskFilesHandlerT& diskFilesHandler ) const
681 {
682  assert( m_maxDiskFilesSize > 0 );
683  assert( m_maxBlockSizeBytes > 0 );
685 
686  diskBlocksInfos.clear();
687  diskFilesHandler.clear();
688 
689  const unsigned int maxBlocksPerFile = m_maxDiskFilesSize / m_maxBlockSizeBytes;
690 
691  unsigned int remainnigBlocksNumber = blocksNumber;
692 
693  while( remainnigBlocksNumber )
694  {
695  const unsigned int fileBlocksNumber = std::min( maxBlocksPerFile, remainnigBlocksNumber );
696  const unsigned long int fileSizeBytes = ((unsigned long int)fileBlocksNumber) *
697  ((unsigned long int)m_maxBlockSizeBytes);
698  assert( fileSizeBytes <= m_maxDiskFilesSize );
699 
700  boost::shared_ptr< OpenDiskFileHandler > newFileHandlerPtr( new OpenDiskFileHandler );
701  if( ! createNewDiskFile( fileSizeBytes, &( newFileHandlerPtr->m_filePtr ),
702  newFileHandlerPtr->m_fullFileName ) )
703  {
704  return false;
705  }
706  diskFilesHandler.push_back( newFileHandlerPtr );
707 
708  for( unsigned int fileBlockIdx = 0 ; fileBlockIdx < fileBlocksNumber ;
709  ++fileBlockIdx )
710  {
711  diskBlocksInfos.push_back( DiskBlockInfo() );
712  diskBlocksInfos.back().m_filePtr = newFileHandlerPtr->m_filePtr;
713  diskBlocksInfos.back().m_fileOff = ((unsigned long int)fileBlockIdx) *
714  ((unsigned long int)m_maxBlockSizeBytes);
715  }
716 
717  remainnigBlocksNumber -= fileBlocksNumber;
718  }
719 
720  return true;
721 }
722 
724  const std::vector< BlockIndex3D >& blocksIndxes )
725 {
726  if( ! blocksIndxes.empty() )
727  {
728  // Allocating new disk blocks
729 
730  std::vector< DiskBlockInfo > newDiskBlocksInfos;
731  OpenDiskFilesHandlerT newDiskFilesHandler;
732  if( ! allocateDiskBlocks( blocksIndxes.size(), newDiskBlocksInfos,
733  newDiskFilesHandler ) )
734  return false;
735  assert( newDiskBlocksInfos.size() == blocksIndxes.size() );
736 
737  m_diskFilesHandler.insert( m_diskFilesHandler.end(),
738  newDiskFilesHandler.begin(), newDiskFilesHandler.end() );
739 
740  unsigned int blocksIndxesIdx = 0;
741  while( blocksIndxesIdx < blocksIndxes.size() )
742  {
743  const BlockIndex3D& bIdx = blocksIndxes[ blocksIndxesIdx ];
744 
745  assert( bIdx.m_dim0Index < m_activeDiskBlocksInfo.size() );
746  assert( bIdx.m_dim1Index < m_activeDiskBlocksInfo[ bIdx.m_dim0Index ].size() );
747  assert( bIdx.m_dim2Index < m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ].size() );
748  assert( m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ][
749  bIdx.m_dim2Index ].m_filePtr == 0 );
750  assert( blocksIndxesIdx < newDiskBlocksInfos.size() );
752  bIdx.m_dim2Index ] = newDiskBlocksInfos[ blocksIndxesIdx ];
753  assert( m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ][
754  bIdx.m_dim2Index ].m_filePtr );
755 
756  ++blocksIndxesIdx;
757  }
758  }
759 
760  return true;
761 }
762 
764  FILE** fileptr, std::string& fullFileName ) const
765 {
766  fullFileName = boost::filesystem::unique_path(
767  boost::filesystem::temp_directory_path() /=
768  boost::filesystem::path( "TerralibExpansibleBandBlocksManager_%%%%-%%%%-%%%%-%%%%" ) ).string();
769  if( fullFileName.empty() )
770  {
771  return false;
772  }
773 
774  (*fileptr) = fopen( fullFileName.c_str(), "wb+" );
775  if( (*fileptr) == 0 )
776  {
777  return false;
778  }
779 
780  long seekoff = (long)( size - 1 );
781 
782  if( 0 != std::fseek( (*fileptr), seekoff, SEEK_SET ) )
783  {
784  fclose( (*fileptr) );
785  remove( fullFileName.c_str() );
786  return false;
787  }
788 
789  unsigned char c = '\0';
790  if( 1 != std::fwrite( &c, 1, 1, (*fileptr) ) )
791  {
792  fclose( (*fileptr) );
793  remove( fullFileName.c_str() );
794  return false;
795  }
796 
797  return true;
798 }
799 
800 
801 
unsigned char * m_currSwapBlockPtr
A pointer to the current block where disk data swap will be done.
RAMBlocksPointersContainerT m_ramBlocksPointers
3D Matrix of active RAM blocks pointers indexed in the form [band][blockYIndex][blockXIndex].
bool addTopBands(const unsigned int &expansionSize, std::vector< BlockIndex3D > &addedBlocksCoords)
New bands will be added at the top of the raster (before the first band).
void shift3DCoords(ContainerType &inputContainer, const int &dim0Shift, const int &dim1Shift, const int &dim2Shift) const
Shift 3D coords.
std::list< OpenDiskFileHandlerPtrT > OpenDiskFilesHandlerT
Open dis files handler type.
bool addBottomBlocks(const unsigned int &expansionSize, const unsigned int &band, std::vector< BlockIndex3D > &addedBlocksCoords)
New blocks will be added at the bottom of the raster.
void * getBlockPointer(unsigned int band, unsigned int x, unsigned int y)
Returns a pointer to the required data block.
bool initialize(const unsigned int maxNumberRAMBlocks, const std::vector< unsigned int > &numbersOfBlocksX, const std::vector< unsigned int > &numbersOfBlocksY, const std::vector< unsigned int > &blocksSizesBytes, const unsigned long int maxDiskFilesSize)
Initialize this instance to an initial state.
ActiveDiskBlocksInfoT m_activeDiskBlocksInfo
3D Matrix of active disk block info indexed as [band][blockYIndex][blockXIndex].
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
An exception class for the TerraLib In-Memory Data Access driver.
unsigned long int m_maxBlockSizeBytes
The maximum global used block size in bytes.
RAMBlocksHandlerT m_activeRAMBlocksHandler
The active RAM blocks handler.
void shiftDim03DCoords(ContainerType &inputContainer, const unsigned int dim0index, const int dim1Shift, const int dim2Shift) const
Shift coords given a fixed dimention 0 index.
bool addBottomBands(const unsigned int &expansionSize, std::vector< BlockIndex3D > &addedBlocksCoords)
New bands will be added at the bottom of the raster (after de the last band).
bool addRightBlocks(const unsigned int &expansionSize, const unsigned int &band, std::vector< BlockIndex3D > &addedBlocksCoords)
New blocks will be added at the right of the raster.
bool allocateAndActivateDiskBlocks(const std::vector< BlockIndex3D > &blocksIndxes)
Allocate and activate disk blocks.
unsigned long int m_maxDiskFilesSize
The maximum temporary disk file size (bytes).
RAM cached and tiled raster band blocks manager.
SwapFifoT::size_type m_nextFIFOPositionOverSwapFifo
The next position where a block swap will occur over m_swapFifo;.
BlockElementT * BlockelementPtrT
Block element pointer type.
bool createNewDiskFile(unsigned long int size, FILE **fileptr, std::string &fullFileName) const
Create a new disk file.
bool addTopBlocks(const unsigned int &expansionSize, const unsigned int &band, std::vector< BlockIndex3D > &addedBlocksCoords)
New blocks will be added at the top of the raster.
void initState()
Initialize this instance to an initial state.
boost::shared_array< BlockElementT > RAMBlockHandlerT
RAM Block handler type;.
bool allocateDiskBlocks(const unsigned int blocksNumber, std::vector< DiskBlockInfo > &diskBlocksInfos, OpenDiskFilesHandlerT &diskFilesHandler) const
Allocate disk blocks.
bool m_isInitialized
Is this instance initialized ?
OpenDiskFilesHandlerT m_diskFilesHandler
The disk files handler;.
unsigned int m_maxNumberRAMBlocks
The maximum number of RAM blocks;.
void free()
Free all allocated internal resources and go back to the initial state.
bool addLeftBlocks(const unsigned int &expansionSize, const unsigned int &band, std::vector< BlockIndex3D > &addedBlocksCoords)
New blocks will be added at the left of the raster.
unsigned char BlockElementT
Block element type.
RAMBlockHandlerT m_swapBlockHandler
An extra block for disk swap purposes.