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 "../core/filesystem/FileSystem.h"
28 #include "../core/encoding/CharEncoding.h"
29 #include "../core/translator/Translator.h"
30 #include "../core/utils/Platform.h"
31 #include "../raster/Band.h"
32 #include "../raster/BandProperty.h"
33 #include "Exception.h"
35 
36 // STL
37 #include <algorithm>
38 #include <cassert>
39 #include <cstdio>
40 
41 // Boost
42 #include <boost/filesystem.hpp>
43 
44 // ---------------------------------------------------------------------------
45 
47 : m_filePtr( nullptr )
48 {
49 }
50 
52 {
53  if( m_filePtr )
54  {
55  remove( m_fullFileName.c_str() );
56  fclose( m_filePtr );
57  }
58 }
59 
60 // ---------------------------------------------------------------------------
61 
63 {
64  m_isInitialized = false;
68  m_currSwapBlockPtr = nullptr;
70 
71 }
72 
74 {
75  initState();
76 }
77 
79 {
80  free();
81 }
82 
84  const unsigned int maxNumberRAMBlocks,
85  const std::vector< unsigned int>& numbersOfBlocksX,
86  const std::vector< unsigned int>& numbersOfBlocksY,
87  const std::vector< unsigned int>& blocksSizesBytes,
88  const unsigned long int maxDiskFilesSize )
89 {
90  if( numbersOfBlocksX.size() == 0 ) return false;
91  if( numbersOfBlocksX.size() != numbersOfBlocksY.size() ) return false;
92  if( numbersOfBlocksY.size() != blocksSizesBytes.size() ) return false;
93 
94  free();
95 
96  m_maxNumberRAMBlocks = maxNumberRAMBlocks;
97  m_maxDiskFilesSize = maxDiskFilesSize;
98 
99  // Discovering boundaries
100 
101  m_maxBlockSizeBytes = 0;
102  unsigned int maxNumbersOfBlocksX = 0;
103  unsigned int maxNumbersOfBlocksY = 0;
104  unsigned int totalRequiredBlocks = 0;
105 
106  {
107  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
108  ++blockBIdx )
109  {
110  if( blocksSizesBytes[ blockBIdx ] == 0 ) return false;
111 
112  if( m_maxBlockSizeBytes < blocksSizesBytes[ blockBIdx ] )
113  m_maxBlockSizeBytes = blocksSizesBytes[ blockBIdx ];
114 
115  if( numbersOfBlocksX[ blockBIdx ] == 0 ) return false;
116 
117  if( maxNumbersOfBlocksX < numbersOfBlocksX[ blockBIdx ] )
118  maxNumbersOfBlocksX = numbersOfBlocksX[ blockBIdx ];
119 
120  if( numbersOfBlocksY[ blockBIdx ] == 0 ) return false;
121 
122  if( maxNumbersOfBlocksY < numbersOfBlocksY[ blockBIdx ] )
123  maxNumbersOfBlocksY = numbersOfBlocksY[ blockBIdx ];
124 
125  totalRequiredBlocks += ( numbersOfBlocksX[ blockBIdx ] *
126  numbersOfBlocksY[ blockBIdx ] );
127  }
128  }
129 
130  if( m_maxBlockSizeBytes > maxDiskFilesSize ) return false;
131 
132  // Allocating RAM blocks
133 
134  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
135 
136  try
137  {
138  m_ramBlocksPointers.resize( numbersOfBlocksX.size() );
139 
140  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
141  ++blockBIdx )
142  {
143  m_ramBlocksPointers[ blockBIdx ].resize( numbersOfBlocksY[ blockBIdx ] );
144 
145  for( unsigned int blockYIdx = 0 ; blockYIdx < numbersOfBlocksY[ blockBIdx ] ;
146  ++blockYIdx )
147  {
148  m_ramBlocksPointers[ blockBIdx ][ blockYIdx ].resize( numbersOfBlocksX[ blockBIdx ], nullptr );
149 
150  for( unsigned int blockXIdx = 0 ; blockXIdx < numbersOfBlocksX[ blockBIdx ] ; ++blockXIdx )
151  {
152  if( m_activeRAMBlocksHandler.size() < maxNumberRAMBlocks )
153  {
154  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
155 
156  m_activeRAMBlocksHandler.push_back( newBlockHandler );
157 
158  m_ramBlocksPointers[ blockBIdx ][ blockYIdx ][ blockXIdx ] =
159  newBlockHandler.get();
160 
161  m_swapFifo.push_back( BlockIndex3D( blockBIdx, blockYIdx, blockXIdx ) );
162  }
163  else
164  {
165  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( blockBIdx,
166  blockYIdx, blockXIdx ) );
167  }
168  }
169  }
170  }
171  }
172  catch(...)
173  {
174  free();
175  return false;
176  }
177 
178  // disk blocks must be used ?
179 
180  try
181  {
182  // allocating the swap block
183 
185 
187 
188  // Allocating disk blocks
189 
190  m_activeDiskBlocksInfo.resize( numbersOfBlocksX.size() );
191 
192  for( unsigned int blockBIdx = 0 ; blockBIdx < numbersOfBlocksX.size() ;
193  ++blockBIdx )
194  {
195  m_activeDiskBlocksInfo[ blockBIdx ].resize( numbersOfBlocksY[ blockBIdx ] );
196 
197  for( unsigned int blockYIdx = 0 ; blockYIdx < numbersOfBlocksY[ blockBIdx ] ;
198  ++blockYIdx )
199  {
200  m_activeDiskBlocksInfo[ blockBIdx ][ blockYIdx ].resize( numbersOfBlocksX[ blockBIdx ] );
201  }
202  }
203 
204  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) )
205  {
206  free();
207  return false;
208  }
209  }
210  catch(...)
211  {
212  free();
213  return false;
214  }
215 
216  // finalizing
217 
218  m_isInitialized = true;
219 
220  return true;
221 }
222 
224 {
225  m_activeRAMBlocksHandler.clear();
226  m_ramBlocksPointers.clear();
227  m_swapFifo.clear();
228  m_activeDiskBlocksInfo.clear();
229  m_diskFilesHandler.clear();
230  m_swapBlockHandler.reset();
231 
232  initState();
233 }
234 
236  unsigned int x, unsigned int y )
237 {
238  assert( m_isInitialized );
239 
240  assert( band < m_ramBlocksPointers.size() );
241  assert( y < m_ramBlocksPointers[ band ].size() );
242  assert( x < m_ramBlocksPointers[ band ][ y ].size() );
244 
246  {
248  }
249  else
250  {
251  // defining the blocks that will manipulated
252 
253  assert( m_nextFIFOPositionOverSwapFifo < m_swapFifo.size() );
255 
256  assert( band < m_activeDiskBlocksInfo.size() );
257  assert( y < m_activeDiskBlocksInfo[ band ].size() );
258  assert( x < m_activeDiskBlocksInfo[ band ][ y ].size() );
259  DiskBlockInfo& inDiskInfo = m_activeDiskBlocksInfo[ band ][ y ][ x ];
260 
261  assert( swapIndex.m_dim0Index < m_activeDiskBlocksInfo.size() );
262  assert( swapIndex.m_dim1Index < m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ].size() );
263  assert( swapIndex.m_dim2Index < m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ].size() );
264  DiskBlockInfo& outDiskInfo = m_activeDiskBlocksInfo[ swapIndex.m_dim0Index ][
265  swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ];
266 
267  // reading the required block into m_currSwapBlockPtr
268 
269  assert( inDiskInfo.m_filePtr );
270  if( 0 != fseek( inDiskInfo.m_filePtr,
271  (long)( inDiskInfo.m_fileOff ), SEEK_SET ) )
272  {
273  throw Exception(TE_TR("File seek error") );
274  }
275 
276  assert( m_currSwapBlockPtr != nullptr );
277  if( 1 != fread( (void*)m_currSwapBlockPtr, (size_t)( m_maxBlockSizeBytes ),
278  1, inDiskInfo.m_filePtr ) )
279  {
280  throw Exception(TE_TR("File read error") );
281  }
282 
283  // Flushing the choosed tile to disk
284 
285  if( 0 != fseek( inDiskInfo.m_filePtr,
286  (long)( inDiskInfo.m_fileOff ), SEEK_SET ) )
287  {
288  throw Exception(TE_TR("File seek error") );
289  }
290 
291  assert( swapIndex.m_dim0Index < m_ramBlocksPointers.size() );
292  assert( swapIndex.m_dim1Index < m_ramBlocksPointers[ swapIndex.m_dim0Index ].size() );
293  assert( swapIndex.m_dim2Index < m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ].size() );
294  assert( m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ] != nullptr );
295  if( 1 != fwrite( (void*)m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ],
296  (size_t)( m_maxBlockSizeBytes ), 1,
297  inDiskInfo.m_filePtr ) )
298  {
299  throw Exception(TE_TR("File write error") );
300  }
301 
302  // updating the indexing structures
303 
305 
306  m_currSwapBlockPtr = m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ];
307 
309 
310  m_ramBlocksPointers[ swapIndex.m_dim0Index ][ swapIndex.m_dim1Index ][ swapIndex.m_dim2Index ] = nullptr;
311 
312  swapIndex.m_dim0Index = band;
313  swapIndex.m_dim1Index = y;
314  swapIndex.m_dim2Index = x;
315 
316  outDiskInfo = inDiskInfo;
317 
318  inDiskInfo.m_filePtr = nullptr;
319  inDiskInfo.m_fileOff = 0;
320 
322  m_swapFifo.size() );
323 
324  // returning the required block pointer
325 
327  }
328 }
329 
331  const unsigned int& expansionSize, const unsigned int& band,
332  std::vector< BlockIndex3D >& addedBlocksCoords )
333 {
334  assert( m_isInitialized );
335  assert( band < m_ramBlocksPointers.size() );
336 
337  addedBlocksCoords.clear();
338 
339  if( expansionSize )
340  {
341  shiftDim03DCoords( m_swapFifo, band, expansionSize, 0 );
342 
343  const unsigned int numberOfBlocksX = (unsigned int)
344  m_ramBlocksPointers[ band ][ 0 ].size();
345 
346  m_ramBlocksPointers[ band ].insert( m_ramBlocksPointers[ band ].begin(),
347  expansionSize,
348  std::vector< BlockelementPtrT >( numberOfBlocksX, nullptr ) );
349 
350  m_activeDiskBlocksInfo[ band ].insert( m_activeDiskBlocksInfo[ band ].begin(),
351  expansionSize,
352  std::vector< DiskBlockInfo >( numberOfBlocksX ) );
353 
354  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
355 
356  for( unsigned int blockYIdx = 0 ; blockYIdx < expansionSize ; ++blockYIdx )
357  {
358  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
359  {
361  {
362  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
363 
364  m_activeRAMBlocksHandler.push_back( newBlockHandler );
365 
366  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
367  newBlockHandler.get();
368 
369  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
370  }
371  else
372  {
373  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
374  }
375 
376  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
377  }
378  }
379 
380  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
381  }
382 
383  return true;
384 }
385 
387  const unsigned int& expansionSize, const unsigned int& band,
388  std::vector< BlockIndex3D >& addedBlocksCoords )
389 {
390  assert( m_isInitialized );
391  assert( band < m_ramBlocksPointers.size() );
392 
393  addedBlocksCoords.clear();
394 
395  if( expansionSize )
396  {
397  const unsigned int numberOfBlocksX = (unsigned int)
398  m_ramBlocksPointers[ band ][ 0 ].size();
399 
400  m_ramBlocksPointers[ band ].insert( m_ramBlocksPointers[ band ].end(),
401  expansionSize,
402  std::vector< BlockelementPtrT >( numberOfBlocksX, nullptr ) );
403 
404  m_activeDiskBlocksInfo[ band ].insert( m_activeDiskBlocksInfo[ band ].end(),
405  expansionSize,
406  std::vector< DiskBlockInfo >( numberOfBlocksX ) );
407 
408  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
409 
410  for( size_t blockYIdx = m_activeDiskBlocksInfo[ band ].size() -
411  expansionSize ; blockYIdx < m_activeDiskBlocksInfo[ band ].size() ;
412  ++blockYIdx )
413  {
414  for( size_t blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
415  {
417  {
418  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
419 
420  m_activeRAMBlocksHandler.push_back( newBlockHandler );
421 
422  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
423  newBlockHandler.get();
424 
425  m_swapFifo.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
426  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
427  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
428  }
429  else
430  {
431  diskBlocksToAllocateIndexes.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
432  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
433  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
434  }
435 
436  addedBlocksCoords.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
437  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
438  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
439  }
440  }
441 
442  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
443  }
444 
445  return true;
446 }
447 
449  const unsigned int& expansionSize, const unsigned int& band,
450  std::vector< BlockIndex3D >& addedBlocksCoords )
451 {
452  assert( m_isInitialized );
453  assert( band < m_ramBlocksPointers.size() );
454 
455  addedBlocksCoords.clear();
456 
457  if( expansionSize )
458  {
459  shiftDim03DCoords( m_swapFifo, band, 0, expansionSize );
460 
461  const unsigned int numberOfBlocksY = (unsigned int)
462  m_ramBlocksPointers[ band ].size();
463 
464  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
465 
466  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
467  {
468  m_ramBlocksPointers[ band ][ blockYIdx ].insert(
469  m_ramBlocksPointers[ band ][ blockYIdx ].begin(),
470  expansionSize, BlockelementPtrT( nullptr ) );
471 
472  m_activeDiskBlocksInfo[ band ][ blockYIdx ].insert(
473  m_activeDiskBlocksInfo[ band ][ blockYIdx ].begin(),
474  expansionSize, DiskBlockInfo() );
475 
476  for( unsigned int blockXIdx = 0 ; blockXIdx < expansionSize ; ++blockXIdx )
477  {
479  {
480  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
481 
482  m_activeRAMBlocksHandler.push_back( newBlockHandler );
483 
484  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
485  newBlockHandler.get();
486 
487  m_swapFifo.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
488  }
489  else
490  {
491  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
492  }
493 
494  addedBlocksCoords.push_back( BlockIndex3D( band, blockYIdx, blockXIdx ) );
495  }
496  }
497 
498  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
499  }
500 
501  return true;
502 }
503 
505  const unsigned int& expansionSize, const unsigned int& band,
506  std::vector< BlockIndex3D >& addedBlocksCoords )
507 {
508  assert( m_isInitialized );
509  assert( band < m_ramBlocksPointers.size() );
510 
511  addedBlocksCoords.clear();
512 
513  if( expansionSize )
514  {
515  const unsigned int numberOfBlocksY = (unsigned int)
516  m_ramBlocksPointers[ band ].size();
517 
518  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
519 
520  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
521  {
522  m_ramBlocksPointers[ band ][ blockYIdx ].insert(
523  m_ramBlocksPointers[ band ][ blockYIdx ].end(),
524  expansionSize, BlockelementPtrT( nullptr ) );
525 
526  m_activeDiskBlocksInfo[ band ][ blockYIdx ].insert(
527  m_activeDiskBlocksInfo[ band ][ blockYIdx ].end(),
528  expansionSize, DiskBlockInfo() );
529 
530  for( size_t blockXIdx = m_ramBlocksPointers[ band ][ blockYIdx ].size()
531  - expansionSize ; blockXIdx <
532  m_ramBlocksPointers[ band ][ blockYIdx ].size() ; ++blockXIdx )
533  {
535  {
536  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
537 
538  m_activeRAMBlocksHandler.push_back( newBlockHandler );
539 
540  m_ramBlocksPointers[ band ][ blockYIdx ][ blockXIdx ] =
541  newBlockHandler.get();
542 
543  m_swapFifo.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
544  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
545  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
546  }
547  else
548  {
549  diskBlocksToAllocateIndexes.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
550  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
551  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
552  }
553 
554  addedBlocksCoords.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(band),
555  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
556  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
557  }
558  }
559 
560  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
561  }
562 
563  return true;
564 }
565 
567  const unsigned int& expansionSize,
568  std::vector< BlockIndex3D >& addedBlocksCoords )
569 {
570  assert( m_isInitialized );
571 
572  addedBlocksCoords.clear();
573 
574  if( expansionSize )
575  {
576  shift3DCoords( m_swapFifo, expansionSize, 0, 0 );
577 
578  const unsigned int numberOfBlocksY = (unsigned int)
579  m_ramBlocksPointers[ 0 ].size();
580  const unsigned int numberOfBlocksX = (unsigned int)
581  m_ramBlocksPointers[ 0 ][ 0 ].size();
582 
583  m_ramBlocksPointers.insert( m_ramBlocksPointers.begin(),
584  expansionSize,
585  std::vector< std::vector< BlockelementPtrT > >( numberOfBlocksY ) );
586 
588  expansionSize,
589  std::vector< std::vector< DiskBlockInfo > >( numberOfBlocksY ) );
590 
591  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
592 
593  for( unsigned int expansionIdx = 0 ; expansionIdx < expansionSize ;
594  ++expansionIdx )
595  {
596  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
597  {
598  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX, nullptr );
599  m_activeDiskBlocksInfo[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX );
600 
601  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
602  {
604  {
605  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
606 
607  m_activeRAMBlocksHandler.push_back( newBlockHandler );
608 
609  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ][ blockXIdx ] =
610  newBlockHandler.get();
611 
612  m_swapFifo.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
613  }
614  else
615  {
616  diskBlocksToAllocateIndexes.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
617  }
618 
619  addedBlocksCoords.push_back( BlockIndex3D( expansionIdx, blockYIdx, blockXIdx ) );
620  }
621  }
622  }
623 
624  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
625  }
626 
627  return true;
628 }
629 
630 bool te::mem::ExpansibleBandBlocksManager::addBottomBands( const unsigned int& expansionSize,
631  std::vector< BlockIndex3D >& addedBlocksCoords )
632 {
633  assert( m_isInitialized );
634 
635  addedBlocksCoords.clear();
636 
637  if( expansionSize )
638  {
639  const unsigned int numberOfBlocksY = (unsigned int)
640  m_ramBlocksPointers[ m_ramBlocksPointers.size() - 1 ].size();
641  const unsigned int numberOfBlocksX = (unsigned int)
642  m_ramBlocksPointers[ m_ramBlocksPointers.size() - 1 ][ 0 ].size();
643 
645  expansionSize,
646  std::vector< std::vector< BlockelementPtrT > >( numberOfBlocksY ) );
647 
649  expansionSize,
650  std::vector< std::vector< DiskBlockInfo > >( numberOfBlocksY ) );
651 
652  std::vector< BlockIndex3D > diskBlocksToAllocateIndexes;
653 
654  for( size_t expansionIdx = m_ramBlocksPointers.size() - expansionSize ;
655  expansionIdx < m_ramBlocksPointers.size() ; ++expansionIdx )
656  {
657  for( unsigned int blockYIdx = 0 ; blockYIdx < numberOfBlocksY ; ++blockYIdx )
658  {
659  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX, nullptr );
660  m_activeDiskBlocksInfo[ expansionIdx ][ blockYIdx ].resize( numberOfBlocksX );
661 
662  for( unsigned int blockXIdx = 0 ; blockXIdx < numberOfBlocksX ; ++blockXIdx )
663  {
665  {
666  RAMBlockHandlerT newBlockHandler( new BlockElementT[ m_maxBlockSizeBytes ] );
667 
668  m_activeRAMBlocksHandler.push_back( newBlockHandler );
669 
670  m_ramBlocksPointers[ expansionIdx ][ blockYIdx ][ blockXIdx ] =
671  newBlockHandler.get();
672 
673  m_swapFifo.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(expansionIdx),
674  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
675  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
676  }
677  else
678  {
679  diskBlocksToAllocateIndexes.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(expansionIdx),
680  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
681  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
682  }
683 
684  addedBlocksCoords.push_back(BlockIndex3D(static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(expansionIdx),
685  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockYIdx),
686  static_cast<te::mem::ExpansibleBandBlocksManager::BlockIndex3D::CoordDataType>(blockXIdx)));
687  }
688  }
689  }
690 
691  if( ! allocateAndActivateDiskBlocks( diskBlocksToAllocateIndexes ) ) return false;
692  }
693 
694  return true;
695 }
696 
698  const unsigned int blocksNumber,
699  std::vector< DiskBlockInfo >& diskBlocksInfos,
700  OpenDiskFilesHandlerT& diskFilesHandler ) const
701 {
702  assert( m_maxDiskFilesSize > 0 );
703  assert( m_maxBlockSizeBytes > 0 );
705 
706  diskBlocksInfos.clear();
707  diskFilesHandler.clear();
708 
709  const unsigned int maxBlocksPerFile = m_maxDiskFilesSize / m_maxBlockSizeBytes;
710 
711  unsigned int remainnigBlocksNumber = blocksNumber;
712 
713  while( remainnigBlocksNumber )
714  {
715  const unsigned int fileBlocksNumber = std::min( maxBlocksPerFile, remainnigBlocksNumber );
716  const unsigned long int fileSizeBytes = ((unsigned long int)fileBlocksNumber) *
717  ((unsigned long int)m_maxBlockSizeBytes);
718  assert( fileSizeBytes <= m_maxDiskFilesSize );
719 
720  boost::shared_ptr< OpenDiskFileHandler > newFileHandlerPtr( new OpenDiskFileHandler );
721  if( ! createNewDiskFile( fileSizeBytes, &( newFileHandlerPtr->m_filePtr ),
722  newFileHandlerPtr->m_fullFileName ) )
723  {
724  return false;
725  }
726  diskFilesHandler.push_back( newFileHandlerPtr );
727 
728  for( unsigned int fileBlockIdx = 0 ; fileBlockIdx < fileBlocksNumber ;
729  ++fileBlockIdx )
730  {
731  diskBlocksInfos.push_back( DiskBlockInfo() );
732  diskBlocksInfos.back().m_filePtr = newFileHandlerPtr->m_filePtr;
733  diskBlocksInfos.back().m_fileOff = ((unsigned long int)fileBlockIdx) *
734  ((unsigned long int)m_maxBlockSizeBytes);
735  }
736 
737  remainnigBlocksNumber -= fileBlocksNumber;
738  }
739 
740  return true;
741 }
742 
744  const std::vector< BlockIndex3D >& blocksIndxes )
745 {
746  if( ! blocksIndxes.empty() )
747  {
748  // Allocating new disk blocks
749 
750  std::vector< DiskBlockInfo > newDiskBlocksInfos;
751  OpenDiskFilesHandlerT newDiskFilesHandler;
752  if (!allocateDiskBlocks(static_cast<unsigned int>(blocksIndxes.size()), newDiskBlocksInfos,
753  newDiskFilesHandler ) )
754  return false;
755  assert( newDiskBlocksInfos.size() == blocksIndxes.size() );
756 
757  m_diskFilesHandler.insert( m_diskFilesHandler.end(),
758  newDiskFilesHandler.begin(), newDiskFilesHandler.end() );
759 
760  unsigned int blocksIndxesIdx = 0;
761  while( blocksIndxesIdx < blocksIndxes.size() )
762  {
763  const BlockIndex3D& bIdx = blocksIndxes[ blocksIndxesIdx ];
764 
765  assert( bIdx.m_dim0Index < m_activeDiskBlocksInfo.size() );
766  assert( bIdx.m_dim1Index < m_activeDiskBlocksInfo[ bIdx.m_dim0Index ].size() );
767  assert( bIdx.m_dim2Index < m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ].size() );
768  assert( m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ][
769  bIdx.m_dim2Index ].m_filePtr == nullptr );
770  assert( blocksIndxesIdx < newDiskBlocksInfos.size() );
772  bIdx.m_dim2Index ] = newDiskBlocksInfos[ blocksIndxesIdx ];
773  assert( m_activeDiskBlocksInfo[ bIdx.m_dim0Index ][ bIdx.m_dim1Index ][
774  bIdx.m_dim2Index ].m_filePtr );
775 
776  ++blocksIndxesIdx;
777  }
778  }
779 
780  return true;
781 }
782 
784  FILE** fileptr, std::string& fullFileName ) const
785 {
786  // trying to use the system temp path
787 
788  bool returnValue = true;
789  long seekoff = (long)size;
790  const boost::filesystem::path randShortFileNamePath(
791  "TerralibExpansibleBandBlocksManager_%%%%-%%%%-%%%%-%%%%" );
792  const unsigned char c = '\0';
793  boost::filesystem::path tempDirPath(te::core::FileSystem::tempDirectoryPath());
794  fullFileName = te::core::FileSystem::uniquePath(
795  (tempDirPath /=
796  randShortFileNamePath).string() );
797 
798  if( fullFileName.empty() )
799  {
800  returnValue = false;
801  }
802  else
803  {
804  try
805  {
806  (*fileptr) = std::fopen( te::core::CharEncoding::fromUTF8(fullFileName).c_str(), "wb+" );
807  if( (*fileptr) == nullptr )
808  {
809  returnValue = false;
810  }
811  else
812  {
813  if( std::fseek( (*fileptr), seekoff, SEEK_SET ) != 0 )
814  {
815  std::fclose( (*fileptr) );
816  std::remove( fullFileName.c_str() );
817  returnValue = false;
818  }
819  else
820  {
821  if( 1 != std::fwrite( &c, 1, 1, (*fileptr) ) )
822  {
823  std::fclose( (*fileptr) );
824  std::remove( fullFileName.c_str() );
825  returnValue = false;
826  }
827  }
828  }
829  }
830  catch(...)
831  {
832  if( (*fileptr) )
833  {
834  std::fclose( (*fileptr) );
835  }
836 
837  std::remove( fullFileName.c_str() );
838  returnValue = false;
839  }
840  }
841 
842  // trying to use the user home path
843 
844  if( ! returnValue )
845  {
846  fullFileName = te::core::FileSystem::uniquePath((
847  boost::filesystem::path( te::core::GetUserDirectory() ) /=
848  randShortFileNamePath).string() );
849 
850  if( fullFileName.empty() )
851  {
852  returnValue = false;
853  }
854  else
855  {
856  try
857  {
858  (*fileptr) = std::fopen( te::core::CharEncoding::fromUTF8(fullFileName).c_str(), "wb+" );
859  if( (*fileptr) == nullptr )
860  {
861  returnValue = false;
862  }
863  else
864  {
865  if( std::fseek( (*fileptr), seekoff, SEEK_SET ) != 0 )
866  {
867  std::fclose( (*fileptr) );
868  std::remove( fullFileName.c_str() );
869  returnValue = false;
870  }
871  else
872  {
873  if( 1 != std::fwrite( &c, 1, 1, (*fileptr) ) )
874  {
875  std::fclose( (*fileptr) );
876  std::remove( fullFileName.c_str() );
877  returnValue = false;
878  }
879  }
880  }
881  }
882  catch(...)
883  {
884  if( (*fileptr) )
885  {
886  std::fclose( (*fileptr) );
887  }
888 
889  std::remove( fullFileName.c_str() );
890  returnValue = false;
891  }
892  }
893  }
894 
895  return returnValue;
896 }
897 
898 
899 
unsigned char * m_currSwapBlockPtr
A pointer to the current block where disk data swap will be done.
unsigned int band
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.
Base exception class for plugin module.
An exception class for the TerraLib In-Memory Data Access driver.
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:242
static std::string fromUTF8(const std::string &src)
Convert a string in UTF-8 to the current locale encoding.
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.
static std::string uniquePath(const std::string &format="%%%%-%%%%-%%%%-%%%%")
Retrives an unique path generated by a given format.
Definition: FileSystem.cpp:70
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.
static std::string tempDirectoryPath()
Retrives the temp directory in UTF-8.
Definition: FileSystem.cpp:64
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.
TECOREEXPORT std::string GetUserDirectory()
Returns the system user home dir path.