Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00042 //----------------------------------------------------------------------------// 00043 00044 #ifndef _INCLUDED_Field3D_SparseFile_H_ 00045 #define _INCLUDED_Field3D_SparseFile_H_ 00046 00047 //----------------------------------------------------------------------------// 00048 00049 #include <vector> 00050 #include <list> 00051 00052 #include <hdf5.h> 00053 00054 #include "Exception.h" 00055 #include "Hdf5Util.h" 00056 #include "SparseDataReader.h" 00057 #include "Traits.h" 00058 00059 //----------------------------------------------------------------------------// 00060 00061 #include "ns.h" 00062 00063 FIELD3D_NAMESPACE_OPEN 00064 00065 //----------------------------------------------------------------------------// 00066 // Forward declarations 00067 //----------------------------------------------------------------------------// 00068 00069 namespace Sparse { 00070 00071 template <typename Data_T> 00072 struct SparseBlock; 00073 00074 } 00075 00076 template <typename Data_T> 00077 class SparseField; 00078 00079 //----------------------------------------------------------------------------// 00080 00081 namespace SparseFile { 00082 00083 //----------------------------------------------------------------------------// 00084 // Reference 00085 //----------------------------------------------------------------------------// 00086 00092 //----------------------------------------------------------------------------// 00093 00094 template <class Data_T> 00095 class Reference 00096 { 00097 public: 00098 00099 // Typedefs ------------------------------------------------------------------ 00100 00101 typedef std::vector<Sparse::SparseBlock<Data_T>*> BlockPtrs; 00102 00103 // Public data members ------------------------------------------------------- 00104 00105 std::string filename; 00106 std::string layerPath; 00107 int valuesPerBlock; 00108 int occupiedBlocks; 00109 00111 std::vector<int> fileBlockIndices; 00114 std::vector<int> blockLoaded; 00117 BlockPtrs blocks; 00121 std::vector<bool> blockUsed; 00124 std::vector<int> loadCounts; 00128 std::vector<int> refCounts; 00132 boost::mutex *blockMutex; 00133 00134 // Ctors, dtor --------------------------------------------------------------- 00135 00137 Reference(const std::string filename, const std::string layerPath); 00138 ~Reference(); 00139 00141 Reference(const Reference &o); 00142 00144 Reference & operator=(const Reference &o); 00145 00146 // Main methods -------------------------------------------------------------- 00147 00149 bool fileIsOpen(); 00151 void setNumBlocks(int numBlocks); 00155 void openFile(); 00159 void loadBlock(int blockIdx); 00161 void unloadBlock(int blockIdx); 00164 void incBlockRef(int blockIdx); 00166 void decBlockRef(int blockIdx); 00168 int blockSize(int blockIdx) const; 00171 int totalLoads() const; 00174 int numLoadedBlocks() const; 00177 int totalLoadedBlocks() const; 00180 float averageLoads() const; 00182 void resetCacheStatistics(); 00183 00184 private: 00185 00187 hid_t m_fileHandle; 00188 00191 Hdf5Util::H5ScopedGopen m_layerGroup; 00192 00195 SparseDataReader<Data_T> *m_reader; 00196 00198 boost::mutex m_mutex; 00199 00200 }; 00201 00202 //----------------------------------------------------------------------------// 00203 // References 00204 //----------------------------------------------------------------------------// 00205 00206 class FileReferences 00207 { 00208 public: 00209 00210 // Main methods -------------------------------------------------------------- 00211 00214 template <class Data_T> 00215 Reference<Data_T>& ref(int idx); 00216 00219 template <class Data_T> 00220 int append(const Reference<Data_T>& ref); 00221 00223 template <class Data_T> 00224 int numRefs() const; 00225 00226 private: 00227 00228 // Data members -------------------------------------------------------------- 00229 00230 std::vector<Reference<half> > m_hRefs; 00231 std::vector<Reference<V3h> > m_vhRefs; 00232 std::vector<Reference<float> > m_fRefs; 00233 std::vector<Reference<V3f> > m_vfRefs; 00234 std::vector<Reference<double> > m_dRefs; 00235 std::vector<Reference<V3d> > m_vdRefs; 00236 00237 }; 00238 00239 //----------------------------------------------------------------------------// 00240 00241 class CacheBlock { 00242 public: 00243 DataTypeEnum blockType; 00244 int refIdx; 00245 int blockIdx; 00246 CacheBlock(DataTypeEnum blockTypeIn, int refIdxIn, int blockIdxIn) : 00247 blockType(blockTypeIn), refIdx(refIdxIn), blockIdx(blockIdxIn) 00248 { } 00249 }; 00250 00251 //----------------------------------------------------------------------------// 00252 00253 } // namespace SparseFile 00254 00255 //----------------------------------------------------------------------------// 00256 // SparseFileManager 00257 //----------------------------------------------------------------------------// 00258 00314 //----------------------------------------------------------------------------// 00315 00316 class SparseFileManager 00317 { 00318 00319 public: 00320 00321 template <class Data_T> 00322 friend class SparseField; 00323 00324 // typedefs ------------------------------------------------------------------ 00325 00326 typedef std::list<SparseFile::CacheBlock> CacheList; 00327 00328 // Main methods -------------------------------------------------------------- 00329 00331 static SparseFileManager &singleton(); 00332 00335 void setLimitMemUse(bool enabled); 00336 00339 bool doLimitMemUse() const; 00340 00342 void setMaxMemUse(float maxMemUse); 00343 00346 void flushCache(); 00347 00349 long long totalLoads(); 00350 00352 long long numLoadedBlocks(); 00353 00355 long long totalLoadedBlocks(); 00356 00359 float cacheFractionLoaded(); 00360 00362 float cacheLoadsPerBlock(); 00363 00366 float cacheEfficiency(); 00367 00369 void resetCacheStatistics(); 00370 00371 //--------------------------------------------------------------------------// 00372 // Utility functions 00373 00378 template <class Data_T> 00379 void incBlockRef(int fileId, int blockIdx); 00380 00385 template <class Data_T> 00386 void decBlockRef(int fileId, int blockIdx); 00387 00391 template <class Data_T> 00392 void activateBlock(int fileId, int blockIdx); 00393 00394 protected: 00395 00397 template <class Data_T> 00398 SparseFile::Reference<Data_T> &reference(int index); 00399 00402 template <class Data_T> 00403 int getNextId(const std::string filename, const std::string layerPath); 00404 00405 template <class Data_T> 00406 void removeFieldFromCache(int refIdx); 00407 00408 private: 00409 00411 SparseFileManager(); 00412 00414 static SparseFileManager *ms_singleton; 00415 00417 void addBlockToCache(DataTypeEnum blockType, int fileId, int blockIdx); 00418 00421 void deallocateBlocks(int bytesNeeded); 00422 00425 template <class Data_T> 00426 int deallocateBlock(const SparseFile::CacheBlock &cb); 00427 00429 template <class Data_T> 00430 void deallocateBlock(CacheList::iterator &it); 00431 00433 float m_maxMemUse; 00434 00436 int m_maxMemUseInBytes; 00437 00439 int m_memUse; 00440 00443 bool m_limitMemUse; 00444 00447 SparseFile::FileReferences m_fileData; 00448 00454 CacheList m_blockCacheList; 00455 00458 CacheList::iterator m_nextBlock; 00459 00462 boost::mutex m_mutex; 00463 00464 }; 00465 00466 //----------------------------------------------------------------------------// 00467 // Reference implementations 00468 //----------------------------------------------------------------------------// 00469 00470 namespace SparseFile { 00471 00472 //----------------------------------------------------------------------------// 00473 00474 template <class Data_T> 00475 Reference<Data_T>::Reference(const std::string a_filename, 00476 const std::string a_layerPath) 00477 : filename(a_filename), layerPath(a_layerPath), 00478 valuesPerBlock(-1), occupiedBlocks(-1), 00479 blockMutex(NULL), m_fileHandle(-1), m_reader(NULL) { 00480 /* Empty */ 00481 } 00482 00483 //----------------------------------------------------------------------------// 00484 00485 template <class Data_T> 00486 Reference<Data_T>::~Reference() 00487 { 00488 if (m_reader) 00489 delete m_reader; 00490 00491 if (blockMutex) 00492 delete [] blockMutex; 00493 } 00494 00495 //----------------------------------------------------------------------------// 00496 00497 template <class Data_T> 00498 Reference<Data_T>::Reference(const Reference<Data_T> &o) 00499 { 00500 m_reader = NULL; 00501 blockMutex = NULL; 00502 *this = o; 00503 } 00504 00505 //----------------------------------------------------------------------------// 00506 00507 template <class Data_T> 00508 Reference<Data_T> & 00509 Reference<Data_T>::operator=(const Reference<Data_T> &o) 00510 { 00511 // Copy public member variables (where appropriate) 00512 filename = o.filename; 00513 layerPath = o.layerPath; 00514 valuesPerBlock = o.valuesPerBlock; 00515 occupiedBlocks = o.occupiedBlocks; 00516 fileBlockIndices = o.fileBlockIndices; 00517 blockLoaded = o.blockLoaded; 00518 blocks = o.blocks; 00519 blockUsed = o.blockUsed; 00520 loadCounts = o.loadCounts; 00521 refCounts = o.refCounts; 00522 if (blockMutex) 00523 delete[] blockMutex; 00524 blockMutex = new boost::mutex[blocks.size()]; 00525 00526 // Copy private member variables (where appropriate) 00527 m_fileHandle = o.m_fileHandle; 00528 // Don't copy id, let hdf5 generate a new one. 00529 if (m_fileHandle >= 0) { 00530 m_layerGroup.open(m_fileHandle, layerPath.c_str()); 00531 } 00532 00533 if (m_reader) 00534 delete m_reader; 00535 m_reader = NULL; 00536 00537 return *this; 00538 } 00539 00540 //----------------------------------------------------------------------------// 00541 00542 template <class Data_T> 00543 bool Reference<Data_T>::fileIsOpen() 00544 { 00545 return m_fileHandle >= 0; 00546 } 00547 00548 //----------------------------------------------------------------------------// 00549 00550 template <class Data_T> 00551 void Reference<Data_T>::setNumBlocks(int numBlocks) 00552 { 00553 boost::mutex::scoped_lock lock(m_mutex); 00554 00555 fileBlockIndices.resize(numBlocks); 00556 blockLoaded.resize(numBlocks, 0); 00557 blocks.resize(numBlocks, 0); 00558 blockUsed.resize(numBlocks, false); 00559 loadCounts.resize(numBlocks, 0); 00560 refCounts.resize(numBlocks, 0); 00561 if (blockMutex) 00562 delete[] blockMutex; 00563 blockMutex = new boost::mutex[numBlocks]; 00564 } 00565 00566 //----------------------------------------------------------------------------// 00567 00568 template <class Data_T> 00569 void Reference<Data_T>::openFile() 00570 { 00571 using namespace Exc; 00572 using namespace Hdf5Util; 00573 00574 boost::mutex::scoped_lock lock_A(m_mutex); 00575 00576 // check that the file wasn't already opened before obtaining the lock 00577 if (fileIsOpen()) { 00578 return; 00579 } 00580 00581 m_fileHandle = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); 00582 if (m_fileHandle < 0) 00583 throw NoSuchFileException(filename); 00584 00585 m_layerGroup.open(m_fileHandle, layerPath.c_str()); 00586 if (m_layerGroup.id() < 0) { 00587 Msg::print(Msg::SevWarning, "In SparseFile::Reference::openFile: " 00588 "Couldn't find layer group " + layerPath + 00589 " in .f3d file "); 00590 throw FileIntegrityException(filename); 00591 } 00592 00593 m_reader = new SparseDataReader<Data_T>(m_layerGroup.id(), valuesPerBlock, 00594 occupiedBlocks); 00595 } 00596 00597 //----------------------------------------------------------------------------// 00598 00599 template <class Data_T> 00600 void Reference<Data_T>::loadBlock(int blockIdx) 00601 { 00602 boost::mutex::scoped_lock lock(m_mutex); 00603 00604 // Allocate the block 00605 blocks[blockIdx]->resize(valuesPerBlock); 00606 assert(blocks[blockIdx]->data.size() > 0); 00607 // Read the data 00608 assert(m_reader); 00609 m_reader->readBlock(fileBlockIndices[blockIdx], blocks[blockIdx]->dataRef()); 00610 // Mark block as loaded 00611 blockLoaded[blockIdx] = 1; 00612 } 00613 00614 //----------------------------------------------------------------------------// 00615 00616 template <class Data_T> 00617 void Reference<Data_T>::unloadBlock(int blockIdx) 00618 { 00619 // Deallocate the block 00620 blocks[blockIdx]->clear(); 00621 00622 // Mark block as unloaded 00623 blockLoaded[blockIdx] = 0; 00624 } 00625 00626 //----------------------------------------------------------------------------// 00627 00628 template <class Data_T> 00629 void Reference<Data_T>::incBlockRef(int blockIdx) 00630 { 00631 boost::mutex::scoped_lock lock(blockMutex[blockIdx]); 00632 ++refCounts[blockIdx]; 00633 } 00634 00635 //----------------------------------------------------------------------------// 00636 00637 template <class Data_T> 00638 void Reference<Data_T>::decBlockRef(int blockIdx) 00639 { 00640 boost::mutex::scoped_lock lock(blockMutex[blockIdx]); 00641 --refCounts[blockIdx]; 00642 } 00643 00644 //----------------------------------------------------------------------------// 00645 00646 template <class Data_T> 00647 int Reference<Data_T>::blockSize(int /* blockIdx */) const 00648 { 00649 return valuesPerBlock * sizeof(Data_T); 00650 } 00651 00652 //----------------------------------------------------------------------------// 00653 00654 template <class Data_T> 00655 int Reference<Data_T>::totalLoads() const 00656 { 00657 std::vector<int>::const_iterator i = loadCounts.begin(); 00658 std::vector<int>::const_iterator end = loadCounts.end(); 00659 int numLoads = 0; 00660 for (; i != end; ++i) 00661 numLoads += *i; 00662 00663 return numLoads; 00664 } 00665 00666 //----------------------------------------------------------------------------// 00667 00668 template <class Data_T> 00669 int Reference<Data_T>::numLoadedBlocks() const 00670 { 00671 std::vector<int>::const_iterator i = blockLoaded.begin(); 00672 std::vector<int>::const_iterator end = blockLoaded.end(); 00673 int numBlocks = 0; 00674 for (; i != end; ++i) 00675 if (*i) 00676 numBlocks++; 00677 00678 return numBlocks; 00679 } 00680 00681 //----------------------------------------------------------------------------// 00682 00683 template <class Data_T> 00684 int Reference<Data_T>::totalLoadedBlocks() const 00685 { 00686 std::vector<int>::const_iterator i = loadCounts.begin(); 00687 std::vector<int>::const_iterator li = blockLoaded.begin(); 00688 std::vector<int>::const_iterator end = loadCounts.end(); 00689 int numBlocks = 0; 00690 00691 if (blockLoaded.size() == 0) { 00692 for (; i != end; ++i) 00693 if (*i) 00694 numBlocks++; 00695 } else { 00696 assert(loadCounts.size() == blockLoaded.size()); 00697 00698 for (; i != end; ++i, ++li) 00699 if (*i || *li) 00700 numBlocks++; 00701 } 00702 00703 return numBlocks; 00704 } 00705 00706 //----------------------------------------------------------------------------// 00707 00708 template <class Data_T> 00709 float Reference<Data_T>::averageLoads() const 00710 { 00711 std::vector<int>::const_iterator i = loadCounts.begin(); 00712 std::vector<int>::const_iterator end = loadCounts.end(); 00713 int numLoads = 0, numBlocks = 0; 00714 for (; i != end; ++i) { 00715 if (*i) { 00716 numLoads += *i; 00717 numBlocks++; 00718 } 00719 } 00720 00721 return (float)numLoads / std::max(1, numBlocks); 00722 } 00723 00724 //----------------------------------------------------------------------------// 00725 00726 template <class Data_T> 00727 void Reference<Data_T>::resetCacheStatistics() 00728 { 00729 std::vector<int>::iterator li = loadCounts.begin(); 00730 std::vector<int>::iterator lend = loadCounts.end(); 00731 for (; li != lend; ++li) 00732 *li = 0; 00733 } 00734 00735 //----------------------------------------------------------------------------// 00736 00737 } // namespace SparseFile 00738 00739 //----------------------------------------------------------------------------// 00740 // Specializations for FileReferences 00741 //----------------------------------------------------------------------------// 00742 00743 namespace SparseFile { 00744 00745 //----------------------------------------------------------------------------// 00746 00747 template <> 00748 inline Reference<half>& 00749 FileReferences::ref(int idx) 00750 { 00751 return m_hRefs[idx]; 00752 } 00753 00754 //----------------------------------------------------------------------------// 00755 00756 template <> 00757 inline Reference<V3h>& 00758 FileReferences::ref(int idx) 00759 { 00760 return m_vhRefs[idx]; 00761 } 00762 00763 //----------------------------------------------------------------------------// 00764 00765 template <> 00766 inline Reference<float>& 00767 FileReferences::ref(int idx) 00768 { 00769 return m_fRefs[idx]; 00770 } 00771 00772 //----------------------------------------------------------------------------// 00773 00774 template <> 00775 inline Reference<V3f>& 00776 FileReferences::ref(int idx) 00777 { 00778 return m_vfRefs[idx]; 00779 } 00780 00781 //----------------------------------------------------------------------------// 00782 00783 template <> 00784 inline Reference<double>& 00785 FileReferences::ref(int idx) 00786 { 00787 return m_dRefs[idx]; 00788 } 00789 00790 //----------------------------------------------------------------------------// 00791 00792 template <> 00793 inline Reference<V3d>& 00794 FileReferences::ref(int idx) 00795 { 00796 return m_vdRefs[idx]; 00797 } 00798 00799 //----------------------------------------------------------------------------// 00800 00801 template <> 00802 inline int FileReferences::append(const Reference<half>& ref) 00803 { 00804 m_hRefs.push_back(ref); 00805 return m_hRefs.size() - 1; 00806 } 00807 00808 //----------------------------------------------------------------------------// 00809 00810 template <> 00811 inline int FileReferences::append(const Reference<V3h>& ref) 00812 { 00813 m_vhRefs.push_back(ref); 00814 return m_vhRefs.size() - 1; 00815 } 00816 00817 //----------------------------------------------------------------------------// 00818 00819 template <> 00820 inline int FileReferences::append(const Reference<float>& ref) 00821 { 00822 m_fRefs.push_back(ref); 00823 return m_fRefs.size() - 1; 00824 } 00825 00826 //----------------------------------------------------------------------------// 00827 00828 template <> 00829 inline int FileReferences::append(const Reference<V3f>& ref) 00830 { 00831 m_vfRefs.push_back(ref); 00832 return m_vfRefs.size() - 1; 00833 } 00834 00835 //----------------------------------------------------------------------------// 00836 00837 template <> 00838 inline int FileReferences::append(const Reference<double>& ref) 00839 { 00840 m_dRefs.push_back(ref); 00841 return m_dRefs.size() - 1; 00842 } 00843 00844 //----------------------------------------------------------------------------// 00845 00846 template <> 00847 inline int FileReferences::append(const Reference<V3d>& ref) 00848 { 00849 m_vdRefs.push_back(ref); 00850 return m_vdRefs.size() - 1; 00851 } 00852 00853 //----------------------------------------------------------------------------// 00854 00855 template <> 00856 inline int FileReferences::numRefs<half>() const 00857 { 00858 return m_hRefs.size(); 00859 } 00860 00861 //----------------------------------------------------------------------------// 00862 00863 template <> 00864 inline int FileReferences::numRefs<V3h>() const 00865 { 00866 return m_vhRefs.size(); 00867 } 00868 00869 //----------------------------------------------------------------------------// 00870 00871 template <> 00872 inline int FileReferences::numRefs<float>() const 00873 { 00874 return m_fRefs.size(); 00875 } 00876 00877 //----------------------------------------------------------------------------// 00878 00879 template <> 00880 inline int FileReferences::numRefs<V3f>() const 00881 { 00882 return m_vfRefs.size(); 00883 } 00884 00885 //----------------------------------------------------------------------------// 00886 00887 template <> 00888 inline int FileReferences::numRefs<double>() const 00889 { 00890 return m_dRefs.size(); 00891 } 00892 00893 //----------------------------------------------------------------------------// 00894 00895 template <> 00896 inline int FileReferences::numRefs<V3d>() const 00897 { 00898 return m_vdRefs.size(); 00899 } 00900 00901 //----------------------------------------------------------------------------// 00902 // Implementations for FileReferences 00903 //----------------------------------------------------------------------------// 00904 00905 template <class Data_T> 00906 Reference<Data_T>& FileReferences::ref(int idx) 00907 { 00908 assert(false && "Do not use memory limiting on sparse fields that aren't " 00909 "simple scalars or vectors!"); 00910 Msg::print(Msg::SevWarning, 00911 "FileReferences::ref(): Do not use memory limiting on sparse " 00912 "fields that aren't simple scalars or vectors!"); 00913 static Reference<Data_T> dummy("", ""); 00914 return dummy; 00915 } 00916 00917 //----------------------------------------------------------------------------// 00918 00919 template <class Data_T> 00920 int FileReferences::append(const Reference<Data_T>& ref) 00921 { 00922 assert(false && "Do not use memory limiting on sparse fields that aren't " 00923 "simple scalars or vectors!"); 00924 Msg::print(Msg::SevWarning, 00925 "FileReferences::append(): Do not use memory limiting on sparse " 00926 "fields that aren't simple scalars or vectors!"); 00927 return -1; 00928 } 00929 00930 //----------------------------------------------------------------------------// 00931 00932 template <class Data_T> 00933 int FileReferences::numRefs() const 00934 { 00935 assert(false && "Do not use memory limiting on sparse fields that aren't " 00936 "simple scalars or vectors!"); 00937 Msg::print(Msg::SevWarning, 00938 "FileReferences::numRefs(): " 00939 "Do not use memory limiting on sparse " 00940 "fields that aren't " 00941 "simple scalars or vectors!"); 00942 return -1; 00943 } 00944 00945 //----------------------------------------------------------------------------// 00946 00947 } // namespace SparseFile 00948 00949 //----------------------------------------------------------------------------// 00950 // SparseFileManager implementations 00951 //----------------------------------------------------------------------------// 00952 00953 template <class Data_T> 00954 int 00955 SparseFileManager::getNextId(const std::string filename, 00956 const std::string layerPath) 00957 { 00958 using namespace SparseFile; 00959 00960 int id = m_fileData.append(Reference<Data_T>(filename, layerPath)); 00961 return id; 00962 } 00963 00964 //----------------------------------------------------------------------------// 00965 00966 template <class Data_T> 00967 void 00968 SparseFileManager::removeFieldFromCache(int refIdx) 00969 { 00970 boost::mutex::scoped_lock lock(m_mutex); 00971 00972 DataTypeEnum blockType = DataTypeTraits<Data_T>::typeEnum(); 00973 SparseFile::Reference<Data_T> &reference = m_fileData.ref<Data_T>(refIdx); 00974 00975 CacheList::iterator it = m_blockCacheList.begin(); 00976 CacheList::iterator end = m_blockCacheList.end(); 00977 CacheList::iterator next; 00978 00979 int bytesFreed = 0; 00980 00981 while (it != end) { 00982 if (it->blockType == blockType && it->refIdx == refIdx) { 00983 if (it == m_nextBlock) { 00984 ++m_nextBlock; 00985 } 00986 next = it; 00987 ++next; 00988 bytesFreed += reference.blockSize(it->blockIdx); 00989 m_blockCacheList.erase(it); 00990 it = next; 00991 } else { 00992 ++it; 00993 } 00994 } 00995 m_memUse -= bytesFreed; 00996 00997 // reset the block indices to -1, to ensure that the cache manager 00998 // won't try to activate a block 00999 reference.fileBlockIndices.clear(); 01000 reference.fileBlockIndices.resize(reference.blocks.size(), -1); 01001 // clear the reference's pointers into the field, and relevant 01002 reference.blocks.clear(); 01003 reference.blockLoaded.clear(); 01004 reference.blockUsed.clear(); 01005 } 01006 01007 //----------------------------------------------------------------------------// 01008 01009 template <class Data_T> 01010 SparseFile::Reference<Data_T> & 01011 SparseFileManager::reference(int index) 01012 { 01013 return m_fileData.ref<Data_T>(index); 01014 } 01015 01016 //----------------------------------------------------------------------------// 01017 01018 template <class Data_T> 01019 void 01020 SparseFileManager::activateBlock(int fileId, int blockIdx) 01021 { 01022 SparseFile::Reference<Data_T> &reference = m_fileData.ref<Data_T>(fileId); 01023 01024 if (reference.fileBlockIndices[blockIdx] >= 0) { 01025 if (!reference.blockLoaded[blockIdx]) { 01026 int blockSize = reference.blockSize(blockIdx); 01027 if (m_limitMemUse) { 01028 // if we already have enough free memory, deallocateBlocks() 01029 // will just return 01030 deallocateBlocks(blockSize); 01031 } 01032 01033 if (!reference.fileIsOpen()) { 01034 reference.openFile(); 01035 } 01036 01037 boost::mutex::scoped_lock lock_A(m_mutex); 01038 boost::mutex::scoped_lock lock_B(reference.blockMutex[blockIdx]); 01039 // check to see if it was loaded between when the function 01040 // started and we got the lock on the block 01041 if (!reference.blockLoaded[blockIdx]) { 01042 reference.loadBlock(blockIdx); 01043 reference.loadCounts[blockIdx]++; 01044 addBlockToCache(DataTypeTraits<Data_T>::typeEnum(), fileId, blockIdx); 01045 m_memUse += blockSize; 01046 } 01047 } 01048 } 01049 reference.blockUsed[blockIdx] = true; 01050 } 01051 01052 //----------------------------------------------------------------------------// 01053 01054 template <class Data_T> 01055 void 01056 SparseFileManager::incBlockRef(int fileId, int blockIdx) 01057 { 01058 SparseFile::Reference<Data_T> &reference = m_fileData.ref<Data_T>(fileId); 01059 01060 if (reference.fileBlockIndices[blockIdx] >= 0) { 01061 reference.incBlockRef(blockIdx); 01062 } 01063 } 01064 01065 //----------------------------------------------------------------------------// 01066 01067 template <class Data_T> 01068 void 01069 SparseFileManager::decBlockRef(int fileId, int blockIdx) 01070 { 01071 SparseFile::Reference<Data_T> &reference = m_fileData.ref<Data_T>(fileId); 01072 01073 if (reference.fileBlockIndices[blockIdx] >= 0) { 01074 reference.decBlockRef(blockIdx); 01075 } 01076 } 01077 01078 //----------------------------------------------------------------------------// 01079 01080 FIELD3D_NAMESPACE_HEADER_CLOSE 01081 01082 //----------------------------------------------------------------------------// 01083 01084 #endif