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